zoukankan      html  css  js  c++  java
  • 为ASP.NET MVC 2.0添加Razor模板引擎 (on .NET4)

    根据ScottGu的博客记述(http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx),在未来不久将会发布一个ASP.NET MVC 3.0的Preview版本,在这个版本中可以使用多个内置的模板引擎,以它发布出来的截图来看,其中包括NHaml,Spark以及微软刚刚发布的ASP.NET Web Pages(Razor)。 ASP.NET Web Pages包含在Web Matrix中,提供了一种新的模板模式,其扩展名为 .vbhtml/.cshtml,可以使用类似以下语法来做视图显示:

    @{
    	var i = 11;
    }
    
    @(i+1)
    <br>
    
    @if (i%2==1){
    	<p>true</p>
    }else{
    	<p>false</p>
    }

    输出结果为:

    12
    <br>
     
    <p>true</p>

    在不久之后Ms还会对此提供Visual Studio 高亮及智能感知支持。

    这种模板如此简捷,如果能用在现有的ASP.NET MVC 2.0上做为一个模板引擎是不错的。

    首先我们要安装ASP.NET Web Pages,下载地址:http://bbs.eice.com.cn/showtopic-409.aspx ,当然直接安装WebMatrix也是可以。

    安装之后在IIS中就会添加对cshtml及vbhtml的支持。

    安装后程序集文件会被复制到Program Files\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies目录下。

    其中包括

    Microsoft.Data.dll
    Microsoft.Web.Infrastructure.dll
    Microsoft.Webpages.Compilation.dll
    Microsoft.Webpages.Configuration.dll
    Microsoft.Webpages.dll
    Microsoft.Webpages.Helpers.dll
    Microsoft.Webpages.Helpers.Toolkit.dll

    下面我们就动手对ASP.NET MVC程序添加一个Razor的模板引擎:

    首先建立一个ASP.NET MVC的项目,然后对其中的Web.Config的system.web/compilation/assemblies节点上添加内容:

    <add assembly="Microsoft.WebPages.Compilation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <add assembly="Microsoft.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <add assembly="Microsoft.WebPages.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <add assembly="Microsoft.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>


    并对system.web/compilation/buildProviders添加内容:

    <add extension=".cshtml" type="Microsoft.WebPages.Compilation.InlinePageBuildProvider" />

    并引用相应的

    Microsoft.Data.dll 
    Microsoft.Webpages.dll 
    Microsoft.Webpages.Helpers.dll 
    Microsoft.Webpages.Compilation.dll 

    几个文件

    准备工作做好了,下面就来实现相应的模板引擎,我们先来实现一个IView对象:

    public class WebPageView : IView
        {
            public WebPageView(string viewPath)
                : this(viewPath, null)
            {
            }
    
            public WebPageView(string viewPath, string masterPath)
            {
                if (string.IsNullOrEmpty(viewPath))
                {
                    throw new ArgumentException("viewPath can't null", "viewPath");
                }
                this.ViewPath = viewPath;
                this.MasterPath = masterPath ?? string.Empty;
            }
    
            public virtual void Render(ViewContext viewContext, TextWriter writer)
            {
                if (viewContext == null)
                {
                    throw new ArgumentNullException("viewContext");
                }
                WebPage page = WebPage.CreateInstanceFromVirtualPath(this.ViewPath);//load cshtml file
                if (page == null)
                {
                    throw new InvalidOperationException("cshtml file not exists");
                }
                else
                {
                    this.RenderViewPage(viewContext, page);
                }
            }
    
            private void RenderViewPage(ViewContext context, WebPage page)
            {
                if (!string.IsNullOrEmpty(this.MasterPath))
                {
                    page.LayoutPage = this.MasterPath;
                }
                page.VirtualPath = this.ViewPath;
                page.ExecutePageHierarchy(CreatePageContext(context)
                    , context.HttpContext.Response.Output, null);
                //execute cshtml file
            }
    
            internal static WebPageContext CreatePageContext(ViewContext content)
            {
                var pc = new WebPageContext();
                var t = pc.GetType();
                t.InvokeMember("HttpContext", BindingFlags.SetProperty | BindingFlags.NonPublic | BindingFlags.Instance
                    , null, pc, new[] { content.HttpContext });
                t.InvokeMember("ViewContext", BindingFlags.SetProperty
                    | BindingFlags.NonPublic | BindingFlags.Instance
                    , null, pc, new[] { content });
                return pc;
            }
    
            /// <summary>Gets or sets the master path.</summary>
            /// <returns>The master path.</returns>
            public string MasterPath { get; private set; }
    
            /// <summary>Gets or sets the view path.</summary>
            /// <returns>The view path.</returns>
            public string ViewPath { get; private set; }
        }

    然后我们再来实现一个IViewEngine对象:

        /// <summary>
        /// WebPage View Engine
        /// </summary>
        class WebPageEngine : VirtualPathProviderViewEngine
        {
           
            public WebPageEngine()
            {
                // how to find the template path
                base.MasterLocationFormats = new string[] { 
                    "~/Views/{1}/{0}.cshtml", 
                    "~/Views/Shared/{0}.cshtml" 
                };
                base.AreaMasterLocationFormats = new string[] { 
                    "~/Areas/{2}/Views/{1}/{0}.cshtml", 
                    "~/Areas/{2}/Views/Shared/{0}.cshtml"
                };
                base.ViewLocationFormats = new string[] { 
                    "~/Views/{1}/{0}.cshtml", 
                   "~/Views/Shared/{0}.cshtml"
                };
                base.AreaViewLocationFormats = new string[] { 
                    "~/Areas/{2}/Views/{1}/{0}.cshtml", 
                    "~/Areas/{2}/Views/Shared/{0}.cshtml" 
                };
                base.PartialViewLocationFormats = base.ViewLocationFormats;
                base.AreaPartialViewLocationFormats = base.AreaViewLocationFormats;
            }
    
            protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
            {
                return new WebPageView(partialPath, null);
            }
    
            protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
            {
                return new WebPageView(viewPath, masterPath);
            }
    
        }

    这样我们就实现了Razor的模板引擎了,我们只要在Global.asax中将模板引擎添加进去:

            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                RegisterRoutes(RouteTable.Routes);
                ViewEngines.Engines.Clear();
                ViewEngines.Engines.Add(new WebPageEngine());
            }

    并且将Global的基类改为WebPageHttpApplication:

    public class MvcApplication : WebPageHttpApplication
    {
    //...
    }

    这样整个程序就可以工作了

    我们在Views/Home下添加一个Index.cshtml:

    @Html.ActionLink("Home","index","User")
    <br>
    @ViewData["Message"]

    这样在我们访问/Home/Index的时候就可以得到ASP.NET MVC默认工程的HomeController.Index所生成的页面了:

    <a href="/User">Home</a>
    <br>
    欢迎使用 ASP.NET MVC!

    可见在这个模板引擎中,先天对ASP.NET MVC有良好的支持,本身已经集成了Helper、ViewData等诸多ASP.NET MVC的特性。

    让我们期待ASP.NET MVC 3.0及Razor对VS的支持吧

    8189E6B8-FBE4-4F01-8F9F-5687C0EA9F59

  • 相关阅读:
    iOS10 的适配问题,你遇到了吗?导航栏标题和返回按钮神奇的消失了
    如何在获取不到第一响应者控件时移除键盘
    类名与字符串的互转
    clang format 官方文档自定义参数介绍(中英文)
    clang format 自定义样式常用参数说明
    Xcode 设置代码不自动换行
    企业项目如何打包成.ipa文件
    多个过渡动画效果
    压栈过渡动画
    底部不规则导航栏2
  • 原文地址:https://www.cnblogs.com/chsword/p/razor_in_aspnet_mvc_2.html
Copyright © 2011-2022 走看看