獨立使用Asp.net Core 的razor模板 (一):Razor引擎的一些細節


    由於最近需要寫一些界面稍微好看點的Winform程序,如果用原生控件,,想要達到好看的程度,需要花費比較大的功夫,因為之前使用過CefSharp,因此發覺如果是使用CEF+Html的方式,界面可以相對容易做的精致一點(其實就是設計完之后,找個前端人員切切圖),但是,使用CEF+Html有個弊端就是,正常的軟件,Header跟Footer大體是通用的,包括一些通用的js/css的引用以及菜單欄等等,,如果直接用html,有個問題就在於,,每個界面都要復制一遍,如果萬一發生修改,每個頁面又要來一次,或許都這里有朋友會說:"那可以使用vue或者ng的模板啊",,實際情況是,,會用的人不多,但是會用jq的人大把.

     由於服務器端有Razor模板,可以很方便的使用Layout以及各種自己封裝的View,但實際情況下,如果單獨把Razor拿出來,實際上是只有將模板string+model解析成新的string的功能而已,因此,想要獨立的使用Razor就需要為獨立的Razor引擎補充一些功能,

 

首先需要補充的就是Layout功能

 開始動工之前,我們先來了解一下一些功能對應到Razor中,是怎么個實現方式的:

 

1.先來看一段簡單的cshtml文件以及生成后的類:

   _Layout.cshtml

   

 1 <html>
 2 <head>
 3     <title></title>
 4 </head>
 5 <body>
 6     
 7     
 8 @RenderBody()
 9 
10 @RenderSection("test",false)
11     
12 </body>
13 </html>
View Code

   Index.cshtml

 1 @{
 2     Layout = "_Layout.cshtml";
 3 }
 4 
 5 <p>sdfsdfsdfs</p>
 6 
 7 
 8 @section test{
 9     <p>ddddddddd</p>
10 }
View Code

   Index.cshtml生成后的代碼:

 1 #pragma warning disable 1591
 2 namespace TEst
 3 {
 4 #line hidden
 5     using System;
 6     using System.Threading.Tasks;
 7     public class TextFile1 : WindowsFormsApp2.RazorViewBase<WindowsFormsApp2.Model>
 8     {
 9 
10 #pragma warning disable 1998
11         public async override global::System.Threading.Tasks.Task ExecuteAsync()
12         {
13             WriteLiteral("\r\n\r\n");
14             WriteLiteral("\r\n");
15 #line 5 "TextFile1.cshtml"
16 
17             Layout = "sdfsdfsdfsf";
18 
19 #line default
20 #line hidden
21             WriteLiteral("\r\n<html>\r\n<head>\r\n    <title></title>\r\n</head>\r\n<body>\r\n");
22             DefineSection("ui", async () =>
23             {
24                 WriteLiteral("\r\n    ");
25 #line 15 "TextFile1.cshtml"
26                 Write(Model.A1);
27 
28 #line default
29 #line hidden
30                 WriteLiteral(";\r\n    ");
31 #line 16 "TextFile1.cshtml"
32                 Write(Model.A1?.StartsWith("sfdsfdf"));
33 
34 #line default
35 #line hidden
36                 WriteLiteral("\r\n        <p></p>\r\n    ");
37             }
38             );
39             WriteLiteral("</body>\r\n</html>");
40         }
41 #pragma warning restore 1998
42     }
43 }
44 #pragma warning restore 1591
View Code

 

1.關於基類,Razor引擎可以設置本次生成的類的基類,並且,要求基類中需要實現幾個函數,已供生成的子類調用

2.@section : 如果使用section關鍵字,編譯后,其實是調用基類的DefineSection(string name, Func<Task> act)函數,

   如:在Layout 中,使用 Html.RenderSesction 函數輸出

    那么在引用該Layout的頁面中,如Index.csthml中,使用

   

1 @section header{
2     sdfsdfsdfsdfs
3      //TODO:其他需要輸出在頭部的標簽
4 }

 

     對應到實際生成的代碼,其實是這樣的

 

 1 DefineSection("header", async () =>
 2             {
 3                 WriteLiteral("\r\n    ");
 4 #line 15 "TextFile1.cshtml"
 5                 Write(Model.A1);
 6 
 7 #line default
 8 #line hidden
 9                 WriteLiteral(";\r\n    ");
10 #line 16 "TextFile1.cshtml"
11                 Write(Model.A1?.StartsWith("sfdsfdf"));
12 
13 #line default
14 #line hidden
15                 WriteLiteral("\r\n        <p></p>\r\n    ");
16             }
17             )

     由生成的代碼可以看到 ,@section 段的使用,需要基類實現 DefineSection(string name, Func<Task> act) 函數,並且將傳入的函數存起來,等待Html.RenderSesction 觸發時調用

 

3.RenderBody,該函數其實是直接把Index.cshtml中,非@section的部分直接輸出,由ExecuteAsync函數開始,所有的WriteLiteral的結果總和,因為@section部分已經是通過DefineSection定義了,所以直接輸出其他結果並不會干擾到

 

4.WriteLiteral和Write: WriteLiteral 直接輸原始數據,Write除非是輸出HtmlString,否則需要轉碼

5.ExecuteAsync函數:Razor其實上是把cshtml轉成對ExecuteAsync函數的內容

6.VS 的IDE支持,,由於.net core 3.0還未出正式版.所以創建的項目為.net 4.5的,而引用的又是asp.net core 的Razor,所以在IDE支持上會有一點點的小區別:

   因此為了省的IDE報太多的錯誤,需要在基類中,添加幾個用於糊弄IDE的函數和屬性:

   

public HttpContextFake Context { set; get; }  //返回自己模擬的一個HttpContext的類,
   protected virtual void DefineSection(string name, Action act)  //函數簽名略微不同
   public virtual void Execute() //IDE認的就是這個函數,不存在會報錯,但沒有實際用途
   

   [Browsable(false),Obsolete]
   public class HttpContextFake
   {
      public System.Web.HttpApplication ApplicationInstance { get; }
    }

 

順帶附上Razor+NaneUI的項目的地址: https://gitee.com/kugar/Kugar.UI.RazorUI

 

以上是Razor一些小的細節,,下篇文章就開始來說怎么創建一個支持Layout的獨立Razor了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM