The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

ASP.NET MVC 開發心得分享 (27):讓 Razor 在 HTML 屬性中輸出 @ 符號

我們有個 ASP.NET MVC 專案上周在做程式碼安全性檢查 Code Review 時,發現開發人員在 Razor 頁面中使用了一些 @Html.Raw() 輸出未經 HTML 編碼的內容,正常來說,在 ASP.NET MVC 網站應用程式中,不應該太過頻繁地出現這種用法,所以只要看到就會特別查看一下,這才發現原來 Razor 從 V2 版開始,就存在著這個小問題 (Bug),所以大家還是要注意一下。

我先來描述一下問題:

基本上,你要在 Razor 頁面中顯示 @ 符號,只要寫上兩的 @ 符號就可以直接輸出 @ 符號,如下圖示:

從上圖你可以看到

  • 第 2 行是個例外,因為 Razor 會自動判斷 @ 是不是 Email 格式,如果符合 Email 格式的話,就會自動跳脫 (Escape) 這個 @ 符號,不會把它當成伺服器內容輸出。
  • 第 4 行則是標準寫法,直接用 @@ 來輸出一個 @ 符號。
  • 第 6 行則是透過 @ 正常輸出一個伺服器端變數 ( ViewBag.Url )
  • 第 19 行則是今天的重點,他在 Visual Studio 裡面出現了錯誤提示!

如果硬是要把網站執行起來,你會看到以下錯誤:
"@" is not valid at the start of a code block.  Only identifiers, keywords, comments, "(" and "{" are valid.

這就很奇怪了,因為只要你想把 @ 字元出現在 Attribute 中,就會出現這個問題,而我們這個客戶,還真的需要將 @ 符號寫在 name 屬性中!

因為你怎樣嘗試,就是無法正常輸出 @ 字元在 HTML 中,都會發生錯誤,所以負責這段程式碼的工程師寫成以下格式:

  • <param name="@Html.Raw("@videoPlayer")" value="4642134676" />


雖然這段程式碼並無安全問題,畢竟這次要輸出的 @videoPlayer 只是個靜態字串而已,但出現 @Html.Raw 我認為就是不太妥當,大家最好不要養成使用 @Html.Raw 的習慣。

所以修改的方法,我認為還有以下 2 種,總之就是比用 @Html.Raw 好一些:

  • <param name="@("@videoPlayer")" value="4642134676" />
  • <param name="@("@")videoPlayer" value="4642134676" />

 

此問題從 Razor V2 開始出現,直到 Razor V3 依然存在,不過剛查到 Razor V4  beta5 已經修正此問題了,各位可能要等到 ASP.NET MVC 6 ( Razor V4 ) 才能正常在 HTML 屬性中使用 @@ 來輸出一個 @ 字元! ^^

 

相關連結