Razor語法的主要設計目標是:讓代碼和標記流能夠一起工作同時盡量不與控制字符沖突。例如,下面的ASPX代碼:
<ul>
<% foreach(var p in Model.Products) { %>
<li><%= p.Name %> ({$selection}lt;%= p.Price %>)</li>
<% } %>
</ul>
現在,我們僅留下我們實際上關注的東西,去除額外的ASPX控制字符,處理後的代碼如下:
<ul>
foreach(var p in Model.Products) {
<li>p.Name ($p.Price)</li>
}
</ul>
很顯然,上面的代碼中並沒有足夠的信息來決定那些是代碼,那些是標記。Razor引擎在設計的時候希望加入盡量少的信息來分辨上面代碼中的代碼和標記。基於Razor引擎的頁面包含了代碼、標記及盡量少的額外標記。因此使用C#Razor語法,上面的代碼變成了:
<ul>
@foreach(var p in Model.Products) {
<li>@p.Name ([email protected])</li>
}
</ul>
這並不是對ASPX語法的一種縫補,Razor利用對C#(或者VB)和HTML語法的充分理解來推斷你要寫的代碼。繼續上面的例子,讓我們一步一步的看Razor是如何解析它的。
<ul>
Razor會一直向前解析直到遇到"@"字符,所以這行Razor會把<ul>歸類為標記並轉到下一行進行處理。
@foreach(var p in Model.Products) {
現在Razor發現了一個"@"字符,"@"字符是Razor中的一個魔力字符,不像ASPX中的"<%=%>",它只有一個字符,接下來解析器會計算出剩下的內容。在ASPX中,我們通過"%>"來聲明代碼塊的結束,但是Razor並沒有自己的語法來聲明代碼塊的結束。 Razor通過最少匹配模式和基於語言的語法來決定代碼塊的結束。在上面的情況中,Razor知道C#中的foreach聲明包含在"{"和"}"字符中,所以當foreach聲明結束的時候,解析引擎返回標記狀態。
<li>@p.Name ([email protected])</li>
剛才說過解析器在到達foreach結束之前會處於代碼模式,那這段代碼如何處理呢?這段代碼更像是標記但我們卻還在foreach聲明代碼塊中。事實上,這是Razor使用基於語言的語法推斷你意圖的另一種情況,我們知道在"{"字符之後會有一些聲明語句,但是,我們發現了"<li>"標記而不是聲明語句,此時Razor會推斷出你實際上是想切換到標記解析而不是代碼解析狀態。所以我們實際上得到的是有三種上下文信息的棧:首先是標記狀態;通過@foreach切換到代碼狀態,通過"<li>"切換回標記狀態;在"<li>"標記結束的時候推斷出已回到foreach主體的代碼狀態。
}
然後解析到foreach語句塊的結束"}"字符,回到標記上下文。
</ul>
接下來我們繼續解析標記直到遇到下一個"@"字符或者到達文件結尾。
查看原文http://blog.andrewnurse.net/CommentView,guid,06dd7c2a-a7ee-461c-b191-83da14f0647b.aspx