MVC Razor简单介绍

  随着MVC3.0RTM版本的发布,大家都从asp.net页面开始转向使用Razor模板引擎。现将Razor学习拿出来和大家分享,如果存在不足的地方欢迎您指出。

     其实在使用<%= %>或者<%: %>在html中调用C#代码时,总在埋怨。这个写法非常麻烦。麻烦就在开与闭区间之间的问题。比如:

     Asp.net: <script src="<%=Url.Content("~/Scripts/jquery-1.7.1.min.js")%>"

     Razor:   <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" 

非常明显,Razor在内部帮我们做了闭合“%>”。其实就是这个小小的闭合让我们可以在html内更加“流畅”的调用服务端代码。故Razor给开发带来了一定的便捷!下面介绍Razor的基本用法。

     1.模板页


       Razor出现后我们就可以选择不再使用asp.net master 模板页。取而代之的是cshtml razor的模板文件。用法个人认为还是和master模板页类似。但在mater模板页的原有功能上有了进一步扩展,更方便开发。比如只要在View文件夹内加入_ViewStart.cshtml文件,我们就无需在每一个具体的View页面引入模板页。减少View页面内的重复代码。具体的可以建立一个MVC3 Application 选择razor模板,VS会自动建立上述机制。下面我们来介绍几个常用的方法:

   1.1. RenderBody

   在Razor引擎中没有了“母版页”,取而代之的是叫做“布局”的页面(_Layout.cshtml)放在了共享视图文件夹中。在这个页面中,会看到标签里有这样一条语句:

@RenderBody()

   其实它的作用和母版页中的服务器控件类似,当创建基于此布局页面的视图时,视图的内容会和布局页面合并,而新创建视图的内容会通过布局页面的@RenderBody()方法呈现   在标签之间。

   这个方法不需要参数,而且只能出现一次。

   1.2. RenderSection

   可以让我们在模板页预设一个区域,未来给继承该模板页的View使用,也就是在母版页中占个位,然后让使用此母版页的子页自己去呈现他们的Section。

   在母版页_Layout.cshtml中定义@RenderSection("Section名")

<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
</head> <body>
<div class="page">
    @RenderSection("SubMenu")
  </div>
</body>
</html>

以上代码第10行,预留出一个SubMenu的section。 熟悉模板页的人,应该明白该处是预留是给未来具体的View页面自定义需要展示的信息的。这个View我们就用默认的Home底下的Index来举例。打开index.cshtml 写入以下代码

@{
    ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>

@section SubMenu{
  <div>抒写需要展示的信息</div>
}

但是当如果使用了_Layout.cshtml做母版页的页没有实现@section SubMenu{...}话,就会报出异常错误,

这是因为我在_Layout.cshtml中使用的是@RenderSection("SubMenu")他要求所有子页都要实现。

解决方法有一下几种方式:

a. 母板页中RenderSection设置第二个参数为false代表它不是必须的,如:@RenderSection("SubMenu",false),默认是:true。

b. 当我在母版页中定义了@RenderSection("SubMenu",false)的时候,我希望当所有子页都没有实现这个Section的时候,母版页可以有自己的呈现内容,就可以用

 <div id="sideBar">
       @if (IsSectionDefined("SubMenu"))
        {
            @RenderSection("SubMenu", false)
        }
        else
        {
            <p>SubMenu Section is not defined!</p>
        }
 </div>

 这样当没有任何页面呈现Section的时候,就会默认显示定义的内容 : "SubMenu Section is not defined!"。

 还有一种比较灵活的方法,通过扩展方法来实现

namespace System.Web.WebPages
{
    public static class Utility
    {
        public static HelperResult RenderSection(this WebPageBase page, string sectionName, Func<object, HelperResult> defaultContent)
        {
            if (page.IsSectionDefined(sectionName))
            {
                return page.RenderSection(sectionName);
            }
            else
            {
                return defaultContent(null);
            }
        }
    }
}

 在母版页中的使用:

 @this.RenderSection("SubMenu", @<div>default section content</div>)

如果子内容页没有呈现Section时,就默认显示<div>default section content</div>.

    1.3. RenderPage

    从名称可以猜出来这个方法是要呈现一个页面。比如网页中固定的头部可以单独放在一个共享的视图文件中,然后在布局页面中通过这个方法调用,用法如下:

  @RenderPage(“~/Views/Shared/_Header.cshtml”) 
  @RenderBody()

代码简洁直观,另外似乎带下划线的视图文件有特殊含义,以后再研究吧。

    二、Razor语法:


    文章开头就已经提到了,个人认为Razor语法的便捷在于razor自动帮助我们闭合C#或VB.NET在html的语法。请看以下代码:

已经给出注释了,仔细阅读并不难理解。您应该也能体会到如果将razor换成asp.net的<%= %>或者<%: %>写法,其实是很“痛苦”的。至于razor的其他用法官方网站已经写的很全面了,比如razor的已经为我们 HTML Encod防止XSS攻击、html中字符串中出现×××@×××.com这样的文本,Razor是可以自动识别成Email格式而不是Razor的关键字。

三、 Razor 语法智能提示:


     该智能提示与VS内的一样,只需Ctrol + J 即可调出。具体的请看下图:

 

posted @ 2013-04-11 14:33  荡来荡去(allen)  阅读(1853)  评论(0编辑  收藏  举报