ASP.NET MVC 第四个预览版(第一部分)

【原文地址】ASP.NET MVC Preview 4 Release (Part 1)
【原文发表日期】 Monday, July 14, 2008 2:18 AM

 

这个新的版本里有一堆新特性和功能,实际上其数目之多,我决定我需要2个帖子才能对它们全部论及,这第一个贴子将讨论第四个预览版中的缓存(Caching),错误处理(Error Handling)和安全(Security)新特性,以及一些测试方面的改进,我下一个贴子将讨论这个版本中新加的AJAX特性。

理解过滤拦截器(Filter Interceptors)

Action过滤器属性(Filter Attributes)是ASP.NET MVC中一个非常有用的扩展功能,这个东西最初是在第二个预览版中加入的,允许你在对MVC控制器的请求中注入拦截代码,在 Controller和它的Action方法执行的前后执行,这可以促成一些非常棒的封装场景,在其中,你能以一种非常干净的,声明的方式轻松地封装和重用功能。

下面是一个极其简单的例子,ScottGuLog过滤器,我可以用它来记录在请求的执行过程中抛出的异常的细节。实现一个定制的过滤器类非常容易,只要继承自ActionFilterAttribute类型,覆盖其中的适当方法,在Controller的Action方法调用之前或之后,或者在ActionResult处理进回复之前或之后运行代码。

ASP.NET MVC 第四个预览版(第一部分)_第1张图片

在ASP.NET MVC Controller中使用过滤器也是非常容易的,只要在Action方法上将其声明为一个属性,或者在Controller类本身之上声明即可(在这个情形下,它将运用于Controller中所有的Action方法):

ASP.NET MVC 第四个预览版(第一部分)_第2张图片

在上面,你可以看到应用了的2个过滤器的例子,我表示要将“ScottGuLog”运用于“About”这个Action方法,而将“HandleError”过滤器运用于HomeController的所有Action方法之上。

 

ASP.NET MVC的以前几个预览版本早就开启了这个过滤器扩展性,但并没有发布预制的过滤器,这第四个版本包含了几个有用的过滤器,可以用来处理输出缓存,错误处理以及安全的场景。

OutputCache过滤器

[OutputCache]过滤器提供了一个简易的方式,将ASP.NET MVC与ASP.NET的输出缓存功能相结合(在ASP.NET MVC第三个预览版中,你要编写代码才能实现这个功能)。

想试验一下的话,修改HomeController(是由VS ASP.NET MVC项目模板生成的)中的Index Action方法的Message值来显示当前时间:

ASP.NET MVC 第四个预览版(第一部分)_第3张图片

在运行这个应用时,每次刷新页面,你都会看到时间戳更新:

ASP.NET MVC 第四个预览版(第一部分)_第4张图片

我们可以在我们的Action方法上加[OutputCache]属性来给这个URL启用输出缓存,我们将使用下面的声明来配置缓存回复10秒钟:

ASP.NET MVC 第四个预览版(第一部分)_第5张图片

现在,当你点击刷新时,你会看到时间戳每10秒钟才更新一次。这是因为action方法每10秒钟才会被调用一次,其他时间的所有请求都是从ASP.NET输出缓存中供应的(意味着不用运行什么代码,所以请求的回复超快)。

除了支持时间间隔外,OutputCache属性还支持标准的 ASP.NET 输出缓存变化选项(随参数,头内容,内容编码以及定制逻辑而变化)。例如,下面的例子会根据PageIndex查询字符串参数的值保存不同的页面缓存版本,然后会根据进来的URL的查询字符串值自动显示正确的版本:

ASP.NET MVC 第四个预览版(第一部分)_第6张图片

你还可以结合ASP.NET的数据库缓存失效功能,该功能允许你在URL依赖的数据库被修改后自动导致缓存失效(小技巧:实现这个功能的最佳方案是在你的web.config中配置一个CacheProfile节,然后在OutputCache属性中配置指向该节点)。

HandleError过滤器

[HandleError]过滤器提供了一种声明的方式,来在一个Controller或一个Action方法上表示,如果在处理一个ASP.NET MVC请求中发生错误的话,应该显示一个友好的错误回复。

要试验一下的话,在项目中加一个新的TestController,实现一个action方法,在其中象下面这样抛出一个异常:

ASP.NET MVC 第四个预览版(第一部分)_第7张图片

在默认情形下,如果将浏览器指向这个URL的话,它会给远程用户显示一个默认的ASP.NET错误网页(除非你去web.config文件中配置了<customErrors>节):

ASP.NET MVC 第四个预览版(第一部分)_第8张图片

我们可以在我们的Controller类或其中的Action方法上加一个[HandleError]属性,来改变要显示的HTML错误,而显示对终端用户比较友好的信息:

ASP.NET MVC 第四个预览版(第一部分)_第9张图片

HandleError过滤器会捕捉住所有的异常(包括处理视图模板时抛出的错误),在出错时显示一个定制的Error视图回复。在默认情形下,它试图在你的项目中寻找一个名为“Error”的视图模板来生成回复。你可以将“Error”视图置于同个Controller相应的视图的目录之中(例如,上面的TestController的\Views\Test目录),也可以置于\Views\Shared文件夹中(系统会先找一个特定于控制器的出错视图,如果没找到的话,会在Shared文件夹中寻找,该文件夹包含了为所有控制器所共享的视图)。

从第四个预览版开始,在你创建新的ASP.NET MVC项目时,Visual Studio现在会自动为你在\Views\Shared文件夹中加一个默认的“Error”视图模板:

ASP.NET MVC 第四个预览版(第一部分)_第10张图片

在我们的TestController类上加[HandleError]属性后,在默认情形下,它会给远程用户显示一个象下面这样的HTML错误页面(注意,它使用了项目的母板页,这样就将错误信息集成进了站点之中)。很明显地,你可以去定制这个Error视图模板,显示你想要的任何HTML或者更加友好的错误信息,下面只不过是随该版本而来的原装的信息:

ASP.NET MVC 第四个预览版(第一部分)_第11张图片

为帮助开发人员,在本地浏览应用时,Visual Studio中由新的项目模板提供的默认的Error视图模板还会显示额外的错误堆栈跟踪信息:

ASP.NET MVC 第四个预览版(第一部分)_第12张图片

你可以在Error视图模板中将代码删除来将其关闭,或者也可以在你的web.config文件中将<customErrors>设成“Off”。

在默认情形下,[HandleError]过滤器将捕捉和处理请求中抛出的所有异常。你也可以在[HandleError]属性上指定 "ExceptionType"和"View"属性来指定你感兴趣的特定异常类型,以及指定定制的错误视图:

ASP.NET MVC 第四个预览版(第一部分)_第13张图片

在上面的代码中,我选择为SqlException和NullReferenceException异常显示定制的错误视图,所有其它的异常则将使用默认的“Error”视图模板。

Authorize过滤器

[Authorize]过滤器提供了一种声明的方式来控制对Controller或Action方法的访问权限,它允许你表示用户必须已经登录,或者要求他们必须是某个特定的用户或是某个特定的安全角色才能访问。这个过滤器可以用于任何类型的认证方式(包括基于Windows以及Forms的认证),还提供了自动将匿名用户转向到登录页面的支持。

要试验一下的话,在Visual Studio中给默认生成的HomeController中的“About” action方法加一个[Authorize]过滤器:

ASP.NET MVC 第四个预览版(第一部分)_第14张图片

象上面这样声明[Authorize]属性表示用户必须已经登录进网站才能请求“About” action。如果还没登录的用户试图访问/Home/About URL的话,他们会无法访问该页。如果web应用是配置成使用基于Windows的认证的话,ASP.NET会自动使用他们的Windows登录身份来认证用户,如果成功的话,就会允许他们访问。如果web应用是配置成使用基于Forms的认证的话,[Authorize]会自动地将用户转向到登录页面以作认证(之后他们就能访问了):

ASP.NET MVC 第四个预览版(第一部分)_第15张图片

[Authorize]属性也允许你将访问权限只授予特定的用户或角色。例如,如果我要将"About" action的访问权限只限于我自己和Bill Gates的话,我可以这么写:

一般来说,除了无关紧要的应用外,你不该在代码中硬写用户名字,一般地,你应该使用象“角色”这样的比较高层次的概念来定义权限,然后另外将用户映射到角色上(例如,使用活动目录或数据库来储存这些映射)。[Authorize]属性通过使用“Roles”属性,极大地方便了对Controllers和Actions的访问的控制:

ASP.NET MVC 第四个预览版(第一部分)_第16张图片

[Authorize]属性并不依赖于任何特定的用户身份或角色管理机制,它只用ASP.NET的"User"对象,该对象是可扩展的,允许使用任何身份系统。

AccountController类

我在上面提到了[Authorize]属性可用于任何认证或用户身份管理系统,你可以编写或使用你想要的任何定制的登录UI或用户/密码管理系统。

但为助你起步,Visual Studio中的ASP.NET MVC项目模板现在包含了一个预制的“AccountController”类以及相关的登录视图,它们实现了表单认证成员系统,支持登录,退出,注册新用户,改变密码等。所有的视图模板和UI都可以轻松地定制,是独立于 AccountController 类或实现的:

ASP.NET MVC 第四个预览版(第一部分)_第17张图片

Site.master模板在右上角也包括了UI,提供登录/退出功能,在使用基于表单的认证时,如果你目前还没认证的话,它会提示你登录:

ASP.NET MVC 第四个预览版(第一部分)_第18张图片

在你通过认证后,它会显示一个欢迎信息,以及一个退出链接:

ASP.NET MVC 第四个预览版(第一部分)_第19张图片

点击上面的Login链接,会将用户转到象下面这样的登录屏幕来做认证:

ASP.NET MVC 第四个预览版(第一部分)_第20张图片

新用户可以点击注册链接来创建新的帐号:

ASP.NET MVC 第四个预览版(第一部分)_第21张图片

错误处理和错误信息显示也是内置的:

ASP.NET MVC 第四个预览版(第一部分)_第22张图片

加到新项目中的AccountController类使用了内置的ASP.NET Membership API来存储和管理用户凭证(Membership系统使用了提供器API,允许接入任何后台存储,ASP.NET包含了内置的Active Directory 和 SQL Server提供器)。如果你不想使用内置的Membership系统的话,你可以保留同样的AccountController action方法签名,视图模板,Forms认证ticket逻辑,只要替换掉AccountController类中的用户帐号逻辑就可以了。在下一个ASP.NET MVC预览版中,我们计划将AccountController和用户身份系统间的交互逻辑封装成一个接口,这将进一步方便你接入你自己的用户存储系统(而不必实现一个完整的membership提供器),以及方便你对它和AccountController进行单元测试。

我们的希望是,这给大家提供了一个很好的快速起步的方式,允许大家在创建一个新项目后,就有一个工作的end to end的安全系统。

测试TempData

在这第四个预览版的第一个贴子里要提到的最后一个改进是对Controller类所做的一些改进,这些改进将允许你更轻松地单元测试TempData集合,TempData 属性允许你保存你要持久到将来一个用户请求的数据,它的意义在于,只持续到下一个请求为止(之后就被去除了)。一般用于这样的MVC场景: 你想要进行一个客户端的重新定向来改变浏览器中的URL,然后想要一种简便的方式来保存临时的数据。

在以前的ASP.NET MVC预览版中,你需要mock对象才能测试TempData集合。在第四个预览版中,你不再需要mock或设置什么了,你现在可以在单元测试中,直接在Controller的TempData集合中添加和核实对象(例如,在调用控制器的一个action方法之前填充它的TempData属性,或者在action方法返回后核实action方法更新了TempData)。TempData集合的实际存储机制现在封装在单独的TempDataProvider属性中了。

结论

希望上面的贴子内容对即将发布的ASP.NET MVC的第四个预览版中的若干新特性和变动提供了一个简单的介绍,下一个贴子将讨论新加的 AJAX 功能,并且示范如何利用它。

希望本文对你有所帮助,

你可能感兴趣的:(asp.net)