独立使用Asp.net Core 的razor模板 (一):Razor引擎的一些细节

    因为最近须要写一些界面稍微好看点的Winform程序,若是用原生控件,,想要达到好看的程度,须要花费比较大的功夫,由于以前使用过CefSharp,所以发觉若是是使用CEF+Html的方式,界面能够相对容易作的精致一点(其实就是设计完以后,找个前端人员切切图),可是,使用CEF+Html有个弊端就是,正常的软件,Header跟Footer大致是通用的,包括一些通用的js/css的引用以及菜单栏等等,,若是直接用html,有个问题就在于,,每一个界面都要复制一遍,若是万一发生修改,每一个页面又要来一次,或许都这里有朋友会说:"那可使用vue或者ng的模板啊",,实际状况是,,会用的人很少,可是会用jq的人大把.css

     因为服务器端有Razor模板,能够很方便的使用Layout以及各类本身封装的View,但实际状况下,若是单独把Razor拿出来,其实是只有将模板string+model解析成新的string的功能而已,所以,想要独立的使用Razor就须要为独立的Razor引擎补充一些功能,html

 

首先须要补充的就是Layout功能前端

 开始动工以前,咱们先来了解一下一些功能对应到Razor中,是怎么个实现方式的:vue

 

1.先来看一段简单的cshtml文件以及生成后的类:git

   _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.cshtmlasp.net

 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生成后的代码:async

 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引擎能够设置本次生成的类的基类,而且,要求基类中须要实现几个函数,已供生成的子类调用ide

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了

相关文章
相关标签/搜索