摘要:ASP.NET MVC3:用Razor實現隱式和顯式程式碼碎塊(code nuggets)
[原文發表位置 ] ASP.NET MVC 3: Implicit and Explicit code nuggets with Razor
[原文發表時間] December 16, 2010 11:23 PM
註:所謂的程式碼碎塊 (code nuggets) 是指在 View 中所寫的 server-side code,以往的 aspx rendering engine 中都要用 <% 和 %> 包起來,但在 Razor engine 中,Razor engine 可以明確的辨識出哪些是 server-side code,本文就是要說明它的機制。
這是我涵蓋ASP.NET MVC3新功能文章系列中的又一篇:
· 用Razor實現內隱式與外顯式程式碼碎塊(今天)
在今天的文章中我將繼續討論如何使用Razor在你的檢視模板中內隱和外顯定義程式碼碎塊(code Nuggets), 並 Demo 一些範例。
用Razor實現流暢程式設計 (Fluid Coding)
Asp.net mvc3發佈包括一個新 「Razor」繪製引擎(和一個現有的.aspx繪製引擎)。你可以從我介紹Razor的文章中更多地瞭解Razor,與我們引進它的緣由以及它所支援的語法。
Razor盡量減少編寫一個檢視模板需要輸入的字元數,實現流暢快捷的寫碼工作流程。與大部分模板的語法不同,你不會因為需要在HTML中標注伺服端程式碼區塊而中斷程式碼編寫。程式碼分析器夠聰明,它能夠從你的程式碼裡推斷出是否為伺服端程式碼。 這使其簡潔、富有表現力的語法輸入能夠乾淨,快速,有趣。
比如下面的Razor程式碼段能用來迭代巡覽一組產品(Products),並輸出一個連結到相應產品頁面的產品名稱<ul>列表:
執行時,上面的程式碼輸出如下:
請注意上面是如何在一個「foreach」迴圈內嵌入兩個程式碼區塊的。其中一塊輸出商品的名字,另一塊則將ProductID包含於一個超連結內。注意我們並不需要明顯的將程式碼碎塊括起來——Razor能足夠聰明地內隱識別出這種情況下程式碼段的起始。
Razor如何內隱識別程式碼碎塊
Razor沒有定義自己的語言。你在Razor程式碼碎塊中所寫的程式碼都是標準C#或VB。這允許你繼續使用現有的語言編寫技能,無需重新學習一種客制語法。
Razor解析器內建了很多智慧能力,任何時候你都無需明確的指定編寫的C#/VB程式碼碎塊的結尾。它讓編碼更流暢,更有效率, 讓模板語法更美妙,乾淨,簡練。下面的場景中,Razor將幫你內隱指定程式碼碎片範圍, 讓你無需明確標明。
獲取屬性
Razor允許你輸出一個變數值,或通過標點「.」引用輸出其屬性。
你也能用標點符號「.」獲取更底層的子屬性
陣列、集合索引
Razor允許你為集合或陣列添加索引:
呼叫方法:
Razor還允許你呼叫方法:
注意上面這些場景中我們是如何不需要顯示定義程式碼塊的結束位置的。 Razor能悄悄地為我們識別出程式碼碎塊的結尾。
Razor針對程式碼碎塊的解析演算法
下面的演算法捕獲了我們支援Razor中的「@」表達式所需要用到的核心解析邏輯,實現上面的內隱式程式碼碎塊:
1. 解析一個標識符——只要遇到在C#或VB中無效的標識符,我們馬上停止解析,轉到第二步;
2. 檢查括弧——如果我們看到「(」或者「[」,移到2.1,否則轉到第三步;
2.1. 一直解析直到遇到相匹配的「)」或「]」 (我們追蹤內嵌的「()」和「[]」對,忽略字串或註解中的「()[]」)。
2.2. 回到第二步。
3. 檢查「.」——如果找到,轉到3.1,否則就不將「.」視為程式碼,轉到第四步
3.1. 如果「.」後面的字元是一個有效標識符,接受「.」,並回到第一步,否則, 轉到第四步。
4. 完成!
程式碼與內容的區別
步驟3.1是上面算法中特別有趣的部分,它讓Razor能區分標識符 (identifier) 是被當作程式碼語句的一部分還是當作靜態內容處理。
注意在上面的片段中我們是如何在程式碼碎塊末尾放置?與!的, 這些都是C#中的合法標識符,而當後面帶有空格的時候,Razor就能夠內隱識別出他們必須被當做靜態字串內容而不是程式碼語句的一部分。這節省了我們的輸入次數,很酷。
Razor中的外顯程式碼碎塊
Razor足夠聰明,能內隱的識別很多程式碼碎塊場景。 但是有的時候你仍然想要/需要顯式指定你的程式碼碎塊語句的範圍。 @(陳述式)語法允許你實現這個:
你能在@()語句中寫任何你想要的C#/VB程式碼語句。 Razor會將()包含的字元視為程式碼碎塊語句的外顯範圍。 下面是我們能用外顯程式碼碎塊功能的幾個場景:
運算數學計算、修改
你能在一個外顯式程式碼碎塊內做數學運算:
於程式碼表達式添加文字
你能用外顯式表達式語句往程式碼碎塊末尾添加靜態文字, 無需擔心它被解析成程式碼:
上面我們往一個<img>元素的src屬性內嵌入了一段程式碼碎塊。它允許我們用類似」/Images/Beverages.jpg」的URLs連結到圖片。 沒有外顯括號, Razor會在CategoryName上尋找一個」.jpg」的屬性(並拋出一個錯誤)。 用外顯的方式,我們能很清楚地指定程式碼結束與文字開始的地方。
使用泛型和Lambdas
外顯式陳述式允許我們在程式碼陳述式中使用泛型型別和泛型方法——從而避免混淆泛型中的<>字元和標籤元素。
還有一個:屬性中的intellisense
我們在上面幾個範例的HTML屬性中使用了程式碼碎塊。 Visual Studio中的Razor程式碼編輯器此時仍然支援VB/C#intellisense,這是一個非常不錯的功能。
下面是在一個<a>href屬性中使用內隱式程式碼碎塊時的C#程式碼intellisense範例:
下面是在一個<img> src=」」屬性中使用一個外顯式程式碼碎塊時的C#intellisense的範例:
注意上面兩種情形中,即使是程式碼陳述式內嵌於一個HTML 屬性中,我們仍能獲得完整的程式碼intellisense(這是現有的.aspx程式碼編輯器所不支援的)。這使得編寫程式碼更加容易, 讓你能隨時隨地利用intellisense。
總結
Razor為流暢編碼工作流實現了一套乾淨簡潔的模板化語法。Razor能內隱式確定程式碼碎塊的範圍,減少按鍵次數,讓你的程式碼真正乾淨。
必要的話, 你也能外顯式用@(陳述式)語法設定程式碼陳述式的範圍, 從而更明白地表達你的意圖, 防止混淆靜態標記與程式碼語句。
希望有所幫助。