ASP.NET MVC的Razor引擎:RazorViewEngine

[来源] 达内    [编辑] 达内   [时间]2012-09-07

基于Web Form引擎的WebFormViewEngine和针对Razor引擎的RazorViewEngine都是抽象类型BuildManagerViewEngine的子类,而后者又继承自VirtualPathProviderViewEngine。

基于Web Form引擎的WebFormViewEngine和针对Razor引擎的RazorViewEngine都是 抽象类型BuildManagerViewEngine的子类,而后者又继承自VirtualPathProviderViewEngine。在这里我们仅仅对实现在RazorViewEngine中View获取的逻辑进行简单介绍。由于Razor引擎下的View通过RazorView对象来表示,而RazorView通过View文件的虚拟路径来构 ,所以RazorViewEngine的View获取机制在于根据当前上下文找到与指定View名称相匹配的View文件(.cshtml或者.vbhtml文件),然后根据该 View文件的虚拟路径创建一个RazorView对象并最终封装成ViewEngineResult对象返回。[本文已经同步到《How ASP.NET MVC Works?》中]

< p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> 实现在RazorViewEngine中的目标View文件的搜索是根据一个预定义顺序进行的。如果当前请求不是针对某个Area的,下面的列表代表了View的搜索顺序:

< ul style="margin: 0px 0px 0px 45px; padding: 0px; word-break: break-all; list-style-type: disc; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); ">
  • ~/Views/{ControllerName}/{ViewName}.cshtml
  • ~/Views/{ControllerName}/{ViewName}.vbhtml
  • ~/Views/Shared/{ViewName}.cshtml
  • ~/Views/Shared/{ViewName}.vbhtml
  • < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> 对于针对某个Area的请求,RazorViewEngine会先按照如下的顺序对目标View进行搜索。如果在这个列表中没有成功找到目标View文件,会继续按照上面的属性进行搜索。

    < ul style="margin: 0px 0px 0px 45px; padding: 0px; word-break: break-all; list-style-type: disc; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); ">
  • ~/Areas/{AreaName}/Views/{ControllerName}/{ViewName}.cshtml
  • ~/Areas/{AreaName}/Views/{ControllerName}/{ViewName}.vbhtml
  • ~/Areas/{AreaName}/Views/ Shared /{ViewName}.cshtml
  • ~/Areas/{AreaName}/Views/ Shared /{ViewName}.vbhtml
  • < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> 如果按照上面的搜索顺序依然找不目标View文件,RazorViewEngine会根据这个列表创建并返回一个ViewEngineResult对象。这里介绍的View搜索机制不仅仅应用于普通的View文件,还应用于Partial View和布局文件的搜索。

    < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> ViewEngine不仅仅通过FindView/FindPartialView根据当前上下文获取指定的View,还通 ReleaseView对指定的View进行释放回收操作。ReleaseView方法在RazorViewEngine的实现很简单,如果指定的View对象的类型实现IDispose接口,它会直接调用其Dispose方法。下图所示的UML体现了Razor引擎涉及的相关类型/接口以及它们之间的相互关系。

    < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> image

    < h6 style="margin: 0px; padding: 0px; font-size: 12px; font-weight: normal; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> 在《ASP.NET MVC的Razor引擎:RazorView》一文中我们创建了一个用于模拟RazorView的SimpleRazorView,现在我们为它创建一个对应的RazorViewEngine,我们直接在该实例项目中添加如下一个SimpleRazorViewEngine。 < div style="margin: 0px; padding: 0px; border: 1px solid silver; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); " id="codeSnippetWrapper">
       1: public class SimpleRazorViewEngine: IViewEngine
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 2: {
       3:     private string
    [] viewLocationFormats = new string[] { 
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 4: "~/Views/{1}/{0}.cshtml",
       5:         "~/Views/{1}/{0}.vbhtml", 
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 6: "~/Views/Shared/{0}.cshtml",
       7:         "~/Views/Shared/{0}.vbhtml" };
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 8: private string [] areaViewLocationFormats = new string[] {
       9:         "~/Areas/{2}/Views/{1}/{0}.cshtml", 
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 10: "~/Areas/{2}/Views/{1}/{0}.vbhtml",
      11:         "~/Areas/{2}/Views/Shared/{0}.cshtml", 
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 12: "~/Areas/{2}/Views/Shared/{0}.vbhtml" };
      13:     
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 14: public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
      15:     {
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 16: return FindView(controllerContext, partialViewName, null, useCache);
      17:     }
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 18: 
      19:     public
     ViewEngineResult FindView(ControllerContext controllerContext, 
    
    string viewName, string masterName, bool useCache)
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 20: {
      21:         string
     controllerName = controllerContext.RouteData.GetRequiredString("controller");
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 22: object areaName;
      23:         List<string> viewLocations = new
     List<string>();
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 24: Array.ForEach(viewLocationFormats, format => viewLocations.Add(string .Format(format, viewName, controllerName)));
      25:         if (controllerContext.RouteData.Values.TryGetValue(
    "area", out areaName))
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 26: {
      27:             Array.ForEach(areaViewLocationFormats, format=>viewLocations.Add(string
    .Format(format,viewName,controllerName, areaName)));
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 28: }
      29:         foreach (string
     viewLocation in viewLocations)
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 30: {
      31:             string filePath = controllerContext.HttpContext.Request.MapPath(viewLocation);
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 32: if (File.Exists(filePath))
      33:             {
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 34: return new ViewEngineResult(new SimpleRazorView(viewLocation),
      35:                     this);
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 36: }
      37:         }
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 38: return new ViewEngineResult(viewLocations);
      39:     }
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 40: 
      41:     public void
     ReleaseView(ControllerContext controllerContext, IView view)
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 42: {
      43:         IDisposable disposable = view as IDisposable;
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 44: if (null != disposable)
      45:         {
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 46: disposable.Dispose();
      47:         }
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 48: }
      49: }
    < h6 style="margin: 0px; padding: 0px; font-size: 12px; font-weight: normal; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> 我们完全按照上面介绍的路径顺序搜索指定的目标View。简单起见,我们在对目标View进行搜索时忽略了指定的布局文件名和对ViewEngineResult的缓存。这个自定义的SimpleRazorViewEngine在Global.asax中通过如下的代码对进行注册。 < div style="margin: 0px; padding: 0px; border: 1px solid silver; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); " id="codeSnippetWrapper">
       1: public class MvcApplication : System.Web.HttpApplication
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 2: {
       3:     protected void Application_Start()
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 4: {
       5:         //其他操作
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 6: ViewEngines.Engines.Clear();
       7:         ViewEngines.Engines.Add(new SimpleRazorViewEngine());
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 8: }
       9: }
    < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); ">我们定义了如下一个HomeController:

    < div style="margin: 0px; padding: 0px; border: 1px solid silver; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); " id="codeSnippetWrapper">
       1: public class HomeController : Controller
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 2: {
       3:     public ActionResult Index()
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 4: {
       5:         Contact contact = new Contact 
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 6: {
       7:              Name             = "张三", 
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 8: PhoneNo = "123456789",
       9:              EmailAddress     = "zhangsan@gmail.com" 
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 10: };
      11:         return View(contact);
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 12: }
      13: }
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 14: 
      15: public class Contact
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 16: {
      17:     [DisplayName("姓名")]
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 18: public string Name { get; set; }
      19:  
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 20: [DisplayName("电话号码")]
      21:     public string PhoneNo { get; set; }
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 22: 
      23:     [DisplayName("电子邮箱地址")]
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 24: public string EmailAddress { get; set; }
      25: }
    < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> 我们的View(“~/Views/Home/Index.cshtml”)很简单。如下面的代码片断所示,这是一个Model类型为Contact的强类型View,在该View中我们直接调用HtmlHelper<TModel>的扩展方法EditorForModel将作为Model的Contact对象以编辑模式呈现在一个表单之中。

    < div style="margin: 0px; padding: 0px; border: 1px solid silver; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); " id="codeSnippetWrapper">
       1: @model Contact
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 2: @{
       3:     ViewBag.Title = Model.Name;
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 4: }
       5:  
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 6: @using (Html.BeginForm())
       7: { 
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 8: @Html.EditorForModel()
       9:     <input type="submit" value
    ="保存" />
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 10: }
    < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> 为了验证我们自定义的SimpleRazorView对布局文件和_ViewStart页面的支持,我们在“~/Views/Shared/”目录下定义了如下一个名为“_Layout.cshtml”的布局文件。布局文件的设置通过定义在“~/Views/”目录下具有如下定义的“_ViewStart.cshtml”文件来指定。

    < div style="margin: 0px; padding: 0px; border: 1px solid silver; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); " id="codeSnippetWrapper">
       1: _Layout.cshtml:
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 2: <html >
       3:     <head
    >
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 4: <title >@ViewBag.Title </title >
       5:     </head
    >    
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 6: <body >
       7:         <h3
    >编辑联系人信息</h3
    >
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 8: @RenderBody()
       9:     </body
    >
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 10: </html >
      11:  
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 12: _ViewStart.cshtml:
      13: @{
    < pre style="margin: 0em; padding: 0px; white-space: pre-wrap; word-wrap: break-word; border-style: none; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 1023px; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; "> 14: Layout = "~/Views/Shared/_Layout.cshtml";
      15: }
    < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> 运行我们的程序后会在浏览器中呈现如下图所示的输出结果,可以看出这和我们直接在Action方法Index中返回一个ViewResult对象没有什么不同。

    < p style="margin: 5px auto 20px; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> image

    资源下载