MVC3 On Razor使用(1):基础部分

Coordinator
Sep 7, 2011 at 9:11 AM




微软在10号发布了ASP.NET MVC3的发布候选版(RC:Release-candidate),该版本提供了Razor视图引擎的智能感知等功能,并同样具备Online许可。


特意下载安装了下,下载地址:http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a920ccee-1397-4feb-824a-2dfefee47d54&displaylang=en


试用了传说中强大的Razor引擎,实在是太棒了。下面是我的一些使用学习体会:


 


一、Razor基础简介


Razor采用了cshtml后缀的文件名,截图如下:


 


 


A、 版面布局


从图上看到,新的视图引擎已经没有了Site.Master这种MasterPage了,取而代之的是_Layout.cshtml和_ViewStart.cshtml。


_Layout.cshtml等同于MasterPage;如下图所示:


 


这个_Layout.cshtml文件中已没有了MasterPage中<asp:ContentPlaceHolder ID="MainContent" runat="server" />的标签语句了,取而代之的是


@RenderBody():呈现子页的主体内容


@RenderSection():呈现特别的节部分。


HelperResult RenderSection(string name, bool required = true);


required默认为true必须覆写,设为false则为可选覆写;


注意的是:该函数在RC版中参数有所改变,参数中optional改为required,据说和VB的关键字冲突


 


下图则为我在子页的页脚部分覆写,在子页实现时,使用@section 自定义节名{ }格式。


 


 


如果我们想在父页里写一个默认实现节,在子页作为可选实现该怎么做呢?


这个在MasterPage是直接支持的,但在Razor里就要稍显复杂些,个人觉得这种写法还可以改进下;


如下图所示,我在父页写了一个默认的页脚实现,如果子页有实现则使用子页实现,没有就用默认实现。


这里要先通过bool IsSectionDefined(string name)函数判断是否有子页实现,有则调用子页实现。


 


 


_ViewStart.cshtml:该页面可以理解为其它View的基类。它默认的代码就3行如下所示:


 


在该页面里定义了其它View的默认MasterPage是“~/Views/Shared/_Layout.cshtml”;


当然在这里还可以定义一些公用的函数及变量,以供其它页面可以直接调用。


 


B、与ASPX语法的区别


 


ASPX:<% %> 


Razor:@{ }


这两种都是代码块的编写符号,只不过用Razor会让代码更加简洁和舒适,下图为对比语法:


clip_image002[4]


 


ASPX:<%= %> 


Razor:@
在Razor中,你只需要用一个”@”字符就可以标识代码块的开始,它能够自动判断后面变量的结束位置,如下图对比看出,使用Razor语法,少写了不少代码。


 


 


而且,Razor解析器内置了很多语言的智能.
大部分情况下,Razor解析器都有足够的能力推导出模板里的一个“@”字符到底是在代码中用到,还是在静态内容中用到。


例如,我在下例中的邮件地址中使用了”@”字符,则scottgu@microsoft.com被解析为静态内容,而@DateTime.Now被解析代码执行了,很强大吧!
如果碰到和代码一样格式的内容(或者你想把代码当作内容看待),你可以显式地打@@来用另外一个”@”字符进行转义。


 


 


ASPX:<%: %> 


Razor:@()


这两种语法都能实现内容的编码,只不过Razor更为方便一些,如下图所示:


 


 


结果输出:<span>文本编码</span>


 


C、其他的一些Razor语法



如上图所示,

@using :导入命名空间

@model:声明页面接收的Model

@section:定义要实现父页的节信息

这里列出的只是一些简单常用的,需要更多语法可以参考API文档。

 


二、MVC3 RC特性展示


相比较MVC2,版本3还是有很大的改进(除了Razor引擎)。


 


A、Partial Page Output Caching(部分页输出缓存)


ASP.NET MVC在第一版的时候就开始支持整页缓存。从ASP.NET MVC V3开始,我们也可以支持部分页缓存了。


这可以很容易的使你部分缓存或者一个response的片段。


 


例如我们要根据一个类别获取产品列表,当请求类别相同时,就输出缓存的产品列表。


如下图所示,Action上定义了输出缓存的过期时间1小时,缓存参数为category。


因此当发生重复请求时,就可以自动输出缓存信息避免频繁查询数据库,减轻服务器负担和提高响应速度:


 


 


 


B、隐式javascript和验证


其中一个比较出色的ASP.NET MVC3的改进是AJAX 和 Validation helpers将会默认使用unobtrusive JavaScript,ajax采用了jquery来编写。


 


 


默认配置节里启用了unobtrusive JavaScript,故将上述js开启后,则验证就为客户端验证。


相比MVC2的ajax验证,不需要在View页里添加<%Html.EnableClientValidation(); %>这行代码了。


 


C、全局过滤器


ASP.NET MVC 支持通过过滤机制来描述性地应用“横切”逻辑。 你可以使用属性语法为控制器和执行函数指定过滤器,如下所示


 


但在使用中,我们常常希望将一些过滤器逻辑应用于程序中的所有控制器上,如Authorize过滤器。


现在ASP.NET MVC3 能够让你指定一个全局的过滤器,这个过滤器可以应用于程序中的所有控制器上。


如下图所示:在Global文件中将自定义过滤器加入GlobalFliterCollection中就可以了


 


 


在MVC3中,这个过滤器的判定逻辑非常灵活,你可以配置一个全局过滤器,使它只在某些条件符合的时候才启用。


如下图所示,我实现了一个全局权限过滤器,在任何页面如果没有登录的话则跳转到LogOn页面。因为是全局的,当跳转到LogOn页面时,


也要判断是否有权限,所以最终页面上什么都不显示。


那如何解决这个问题呢,让LogOn页面不应用该全局权限呢?


如下图所示:我们实现一个IFilterProvider,在里面过滤掉LogOn页面而应用于其他的页面。代码如下:


 


在使用Authorize过滤器时,发现了一个bug,就是当没有权限时,系统会自动跳到“Account/LogIn”页面,而不是跳转到webconfig中设置的页面。


<authentication mode="Forms">
      <forms  loginUrl="~/Account/LogOn" timeout="2880" />
</authentication>


这个设置好像不起作用了,通过查看ScottGu’s Blog,知道这是一个bug,解决方案就是在Configuration配置节下加入


<appSettings>
    <add key="autoFormsAuthentication" value="false" />
</appSettings>


我想在正式版中不会再有这个问题了。


 


还有其他的一些新的特性,可以参考http://tech.it168.com/a2010/1111/1124/000001124749_1.shtml