ASPNET編程經常會碰到在前台頁面代碼中要使用(或綁定)後台程序中變量值的問題一般有<%= str%>和<%# str %>兩種方式這裡簡單總結一下如有錯誤或異議之處敬請各位指教
一方面這裡所講的前台即通常的aspx文件後台指的是與aspx相關聯的CodeBehind文件後綴名為aspxcs另一方面這裡的綁定是指用戶發出訪問某一頁面指令後服務器端在執行過程中就已經將前台代碼進行了賦值而後生成html格式回傳客戶端顯示而並非已經顯示到客戶端後然後通過其他方法(如ajax)去服務器端獲取相應變量
備注上面說的兩個文件是常見的代碼隱藏(codebehind)模式還有一種是代碼嵌入(codebeside inline)模式那就是只存在aspx一個文件而後台代碼則寫入此文件的<script type="text/javascript" runat="server"></script>之中(還有一些語法上區別)這對於本文討論的問題略有影響因為代碼嵌入是聲明性代碼與C#/VBNET代碼都一起編譯到一個類裡面而代碼隱藏則將聲明性代碼與C#/VBNET代碼分開幾次進行翻譯/編譯因此前者是局部與局部(partial)的關系後者基類與派生類的關系但這僅僅影響所能綁定變量的范圍(與修飾符有關)下面會提到以下均以代碼隱藏模式為例
一般來說在前台代碼的三種位置可能會用到(綁定)後台變量
服務器端控件屬性或HTML標簽屬性
JavaScript代碼中
Html顯示內容的位置(也就是開始標簽與結束標簽之間的內容如<div>這裡</div>(Html標簽)或者<asp:Label ID="Label" runat="server" Text="Label">這裡</asp:Label>(服務器端控件)它作為占位符把變量顯示於符號出現的位置)
對於第一種位置有一些約束條件
()一般的屬性要求是字符串型或數值型(下面會提到有些服務器端屬性支持屬性為數據集合)
()並不是所有的屬性都可以綁定變量有些屬性例如runat屬性必須是"server"常量即使綁定的字符串是server也會導致分析器分析時出錯
()有一種屬性他要求屬性值有約束(類型約束比如服務器端控件要求TabIndex屬性是short類型或者字符串內容有約束)也應該在綁定時滿足否則依然可能編譯時報錯
()還一種屬性雖然屬性本身有約束但即使綁定的變量不滿足約束也可以編譯通過比如input的checked屬性它只有checked字符串是合法的但如果通過綁定獲取到的字符串不是checked那麼這些屬性將有自己內部處理機制來保證可以正常使用
()還要注意即使對於同一類屬性服務器端和HTML的屬性的處理機制也不同同樣是TabIndex(tabIndex)前者如果不滿足則分析器錯誤後者則忽略這一問題
對於第二種位置一般只要綁定的後台變量和JavaScript中數據類型兼容即可
對於第三種位置如果綁定出現的位置不在服務器端控件內部則沒有約束條件只要是常量字符串可以出現的位置均可以綁定但是對於置於服務器端控件內部也就是上面那種<asp:Label ID="Label" runat="server" Text="Label">這裡</asp:Label>的方式則有約束條件通過總結歸納為四類服務器端控件如果綁定的代碼出現在這些控件的開始和結束標簽之間(這裡所說的控件是指如果綁定代碼外有多層的嵌套控件包圍則是指包圍綁定代碼的最內層控件)有不同的顯示結果
()約束型控件這類控件要求它的開始標簽和結束標簽中只能包含指定的子控件因此如果在這裡出現代碼塊將編譯錯誤例如
<asp:DataList runat="server"></asp:DataList>在它之間要求必須嵌套<ItemTemplate></ItemTemplate>
()非嵌套類控件這類控件不允許在內部嵌套其他控件或標簽只能是常量字符串它會將開始標簽和結束標簽中常量字符串內容作為他的屬性例如上面提到的TextBox它會將標簽間內容作為它的Text屬性值
()嵌套類控件這類控件可以嵌套其他任意控件也可以包含字符串因此可以正常顯示綁定代碼塊所表示的字符串內容例如Label控件Panel等
()數據綁定類控件這類控件是ASPNET提供的服務器端控件除了可以綁定普通的變量類型也可以綁定一個數據集合(只能采取下面的第二種方式實現)
關於是否加引號在以上三個位置使用時是否應該將<%= str%>或<%# str %>置於單引號或雙引號中呢?對於在不同位置處理的方式是不同的(具體請在下面兩種方式的具體介紹時加以體會)
()對於第一種位置由於JavaScript是弱類型的如果綁定時加引號顯然就認為就當做字符串來處理這始終是正確的如果綁定時不加引號它將認為這是個數值型的那麼如果獲取的真是數值當然可以如果是非數值型則將產生腳本錯誤這即使對於JavaScript賦值常量時也是同樣的
以下為引用的內容
var test = b;//運行時報錯
var test=;//正確是數值型
var test="b";//正確字符串型
()對於第二種位置經過測試無論是對於服務器端控件屬性還是HTML標簽屬性加引號總是正確的如果不加引號則兩種屬性的處理方式不同
對於服務器端控件屬性如果綁定的代碼塊不加引號則編譯時會提示“驗證(ASPNET)特性值前後必須加引號”的警告信息但是生成為HTML後對應生成的HTML屬性已經被加上引號並獲取了正確的綁定結果因此加不加引號不會影響使用但是建議對於規范的代碼還是加上為好
對於HTML標簽屬性如果不加引號則編譯時會提示“驗證(XHTML Transitional): 特性值前後必須加引號”的警告信息並且生成為HTML屬性也確實沒有加上引號那麼雖然屬性後面確實是沒有加上引號的正確的綁定值但是不一定能展示出想要看到的結果比如對於input標簽的value屬性如果綁定的字符串是" hello world from variable”則在客戶端的input顯示出的內容實際上只是"hello”字符串生效的屬性值是一個被截斷的字符串它從屬性後的一串字符串(若未加引號)的第一個非空字符開始截止到下一個空字符的前一個字符為止(比如對於" hello world”結果將是"hello”)因此加上引號是必須的
()對於第三種位置加與不加引號獲取的值及其顯示均不受影響
因此建議所有綁定表達式都加上引號作為字符串獲取然後根據實際需求用相應函數進行轉換得到所需要的類型
另外這裡所說的後台變量是泛指的包括如下
成員變量
方法或屬性的返回值
表達式也就是所有後台能夠執行的代碼運行後所得到的值(也就是直接將後台代碼寫在前台代碼中記得使用完全限定名或在後台中using相關namespace)
數據集合
後台變量有一些約束條件需要滿足
()變量修飾符要求變量是靜態或者實例字段均可對於代碼隱藏模式的ASPNET以上的所述的變量必須為public或protected類型(因為是基類與派生類的關系)private或者internal都不行而代碼嵌入模式則任何修飾符的變量均可訪問(一個類內部的關系)
()變量類型要求由於前台屬性一般是字符串類型而JavaScript基本類型也就是字符串型數字型布爾型因此對應的變量應該也是這幾種方式其余類型如果不被支持(如復雜類型數組引用類型等)前台獲取的就是調用了變量的ToString()方法所得到的字符串因此在綁定時要根據情況看是否能進行隱式類型轉換必要時還要用相關函數來強制轉換以保證前台可以獲得正確的值當然對於數據綁定類控件它的有些屬性可以為數據集合但這時的綁定只能通過下面第二種方式才被支持
以上是一些概念和基本約束這些都是兩種方式都應該滿足的下面具體介紹兩種方式來實現前台代碼中(以下稱為代碼塊)綁定後台變量的功能
From:http://tw.wingwit.com/Article/program/net/201311/14211.html