[转] ASP.NET MVC 中你必须知道的 13 个扩展点

ScottGu 在其 最新的博文 中推荐了 Simone Chiaretta 的文章 13 ASP.NET MVC extensibility points you have to know,该文章为我们简单介绍了  ASP.NET MVC  中的 13 个扩展点。Keyvan Nayyeri(与Simone合著了 Beginning ASP.NET MVC 1.0 一书)又陆续发表了一些文章,对这13个扩展点分别进行深入的讨论。我将在以后的随笔中对这些文章逐一进行翻译,希望能对大家有所帮助。

ASP.NET MVC 设计的主要原则之一是可扩展性。处理管线(processing pipeline)上的所有(或大多数)东西都是可替换的。因此,如果您不喜欢ASP.NET MVC 所使用的约定(或缺乏某些约定),您可以创建自己的服务来支持您的约定,并将其注入到主管线中。

在本文中,我们将从管线开始直到视图呈现,逐一向您展示每个ASP.NET MVC开发者都必须了解13个扩展点。

1.RouteConstraint

通常情况下你可以使用正则表达式对 url 参数进行约束,但如果您的约束不仅仅取决于单一参数,您可以实现 IRouteConstrains 的方法,并在其中添加你的验证逻辑。

比如对日期的验证,url中可能会包含年、月、日,而你需要验证这三者是否可以组合成一个有效的日期。

2.RouteHandler

RouteHandler 是在路由选择之后进行处理的组件,它并不仅仅针对ASP.NET MVC。显然,如果您改变了RouteHandler,那么对请求的处理将不再使用ASP.NET MVC,但这在您使用其他HttpHandler或 经典的WebForm 进行路由处理时却是非常有用的。

3.ControllerFactory

ControllerFactory 是基于路由的组件,它选择正确的 controller 并对其实例化。default factory 会查找实现了 IController 并且以 Controller 结尾的类,然后通过反射使用无参构造函数进行实例化。

但如果您希望使用依赖注入,就不能再使用 default factory,而必须使用支持 IoC 的 controller factory。MvcContrib 和 Ninject Controller Factory 都包含支持 IoC 容器的controller factory。

4.ActionInvoker

ActionInvoker 顾名思义是负责调用(invoke)action的。默认的 action invoker 通过方法名、action 名或其他可能的 selector attribute 来查找 action,然后调用 action 方法以及定义的filter,最终执行得到action result。

你会发现大部分执行管线存在于 ControllerActionInvoker 类的逻辑之中。因此,如果希望改变这些约定,如 action 方法的选择逻辑、http 参数映射到 action 参数的方式、选择和执行filter的方式等,您需要扩展该类并重写需要修改的方法。

可以参阅 NinjectActionInvoker I developed to allow injection of dependencies inside filters

5.ActionMethodSelectorAttribute

使用默认的 action invoker 时,action 的选择是基于名称的。您也可以实现自己的 Method Selector 以改善对于action的选择。在框架中已经包含了 AcceptVerbs 特性,它允许您指定使用哪一个 HTTP Verb 来处理action的响应。

例如,您也许会希望基于浏览器所支持的语言或浏览器类型(如移动设备的浏览器或桌面浏览器)来进行action的选取。

6.AuthorizationFilter

这种过滤器是在 action 执行之前执行的,用来确保请求是有效的。

框架中已经包含了一些autorization过滤器,最有名的莫过于 Authorize 特性,它用来检查当前用户是否允许执行该action。另一个是 用来阻止CSRF攻击的ValidateAntiForgeryToken。如果您希望实现自己的authorization,那么必须实现接口。例如,日期中的小时。

7.ActionFilter

Action Filters在action执行前后执行。OutputCache过滤器是几个核心过滤器之一。这可能是您最有可能使用的扩展点,并且在我看来,controller只关心它的主要工作,而view所需要的所有其他数据都必须从action过滤器内部获取,这样的实现对于一个组织良好的view来说,是十分关键的。

8.ModelBinder

默认的 model binder 使用参数名称进行 HTTP 参数到 action 方法参数的映射。例如,http 参数 user.address.city 将映射到方法参数user的Address属性的City属性。DefaultModelBinder 也同样适用于数组和其他列表类型。

更进一步来说,例如,您可能希望从数据库中进行检索,直接根据 person 的 id 将其转换为 Person 对象。Timothy Khouri(网名SingingEels)在他的文章 Model Binders in ASP.NET MVC 中更好的阐述了这种方法。他的代码基于 Preview 5,但其理念是一样的。

9.ControllerBase

所有的 Controller 均继承自基类 Controller。要想在 action 中封装自己的逻辑和约定,创建自己的父类使所有 Controller 继承自该类,是一种很好的方式。

10.ResultFilter

与 ActionFilter 类似,ResultFilters 在 ActionResult 前后执行。OutputCache 过滤器也可以作为 ResultFilter 的示例。另外,比较常用的诠释这种过滤器的示例是日志记录。如果您希望在页面返回给用户时记录日志,可以编写自定义的 RenderFilter,在 ActionResult 执行之后记录日志。

11.ActionResult

ASP.NET MVC 提供了很多 result 用来呈现视图、JSON、纯文本、文件并重定向到其他 action。如果您需要其他类型的 result,可以自定义 ActionResult,并实现 ExecuteResult方法。例如,如果您希望将 PDF 文件作为结果发送,您需要使用 PDF 库编写能够生成 PDF 的 ActionResult。又如RSS feed,可参见 how to write a RssResult in this post

12.ViewEngine

您可能不需要编写自己的 view engine,但您也许可以考虑使用其他引擎来替代默认的 WebForm view engine。在我看来,最有趣的引擎就是 Spark

如果您确实希望编写自己的 view engine,可以看一下 Brad Wilson 的文章: Partial Rendering & View Engines in ASP.NET MVC

13.HtmlHelper

视图必须十分简单整洁,它们只能包含 html 标记并调用 HtmlHelper 的辅助方法。视图中不能包含任何代码,所以辅助方法必须十分方便,使您可以将代码从视图中提取出来,放到一个可测试的环境中去。正如 Rob Conery 所说:如果有if,就构造辅助方法(If there‘s an IF, make a Helper)。

什么是 HtmlHelper 辅助方法?其实就是 HtmlHelper 类的扩展方法,这是唯一的要求。

你可以从Rob的文章 Avoiding Tag Soup 中了解到为什么说 HtmlHelper 是封装视图中代码的好方法。

在您的应用中该使用哪个呢?

正如您所猜测的那样,并不是所有的应用都需要扩展以上的 13 个扩展点。最可能在所有应用中进行扩展的是 ActionFilter 和 HtmlHelper。另外,您很可能会使用其他人编写的扩展,如使用了 IoC 容器的 ControllerFactory 或用来摆脱 WebForm 的 ViewEngine。

但是,学习这些扩展点并进行尝试是十分重要的,这样您才会做出选择,并随时准备在必要的时候使用这些强大的扩展点。下周我将发表一些文章来阐述如何使用这些扩展点。

如果您想详细了解更多关于该话题的内容,可以考虑购买即将出版的 Beginning ASP.NET MVC(我是作者之一)或 Professional ASP.NET MVC(ASP.NET MVC开发团队编写)或 ASP.NET MVC in Action (Jeffrey PalermoBen Scheirman著)。

我是否遗漏了某些您认为重要的扩展点呢?您是否使用过我上面提到的扩展点呢?我很想听听您所遇到的场景。

时间: 2024-10-13 16:31:46

[转] ASP.NET MVC 中你必须知道的 13 个扩展点的相关文章

MVC中你必须知道的13个扩展点

MVC中你必须知道的13个扩展点 pasting 转:http://www.cnblogs.com/kirinboy/archive/2009/06/01/13-asp-net-mvc-extensibility-points-you-have-to-know.html ScottGu在其最新的博文中推荐了Simone Chiaretta的文章13 ASP.NET MVC extensibility points you have to know,该文章为我们简单介绍了ASP.NET MVC中的

log4net 使用总结- (2)在ASP.NET MVC 中使用

log4net在ASP.NET MVC中的配置,还有一种配置方式,即不在web.config中,而是单独新建一个log4net.config 在根目录下 第一.引用log4net.dll 第二.在站点根目录下增加log4net.config <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="

ASP.NET MVC中使用异步控制器

线程池 一直想把项目改写成异步,但是ASP.NETMVC3下写的过于繁琐,.NET 4.5与ASP.NET MVC下代码写起来就比较简单了, MS好像也一直喜欢这样搞,每一个成熟的东西,都要演变好几个版本,才能趋于规范. ASP.NET MVC 中为什么需要使用异步呢,IIS有一个线程池来处理用户的请求,当一个新的请求过来时,将调度池中的线程以处理该请求,然而,但并发量很高的情况下,池中的线程已经不能够满足这么多的请求时候,池中的每一个线程都处于忙的状态则在处理请求时将阻塞处理请求的线程,并且该

ASP.NET MVC中使用ASP.NET AJAX异步访问WebService

使用过ASP.NET AJAX的朋友都知道,怎么通过ASP.NET AJAX在客户端访问WebService,其实在ASP.NET MVC中使用ASP.NET AJAX异步访问WebService 也没什么大的差别. 在ASP.NET应用程序里使用ASP.NET AJAX访问WebService通常都是通过ScriptMananger引入WebService生成客户端代理的方法,同时也可以使用Microsoft Ajax Library来完成.本文将介绍在ASP.NET MVC中使用ASP.NE

ASP.NET MVC中使用FluentValidation验证实体

1.FluentValidation介绍 FluentValidation是与ASP.NET DataAnnotataion Attribute验证实体不同的数据验证组件,提供了将实体与验证分离开来的验证方式,同时FluentValidation还提供了表达式链式语法. 2.安装FluentValidation FluentValidation地址:http://fluentvalidation.codeplex.com/ 使用Visual Studio的管理NuGet程序包安装FluentVa

ASP.NET MVC 中应用Windows服务以及Webservice服务开发分布式定时器

ASP.NET MVC 中应用Windows服务以及Webservice服务开发分布式定时器一:闲谈一下:1.现在任务跟踪管理系统已经开发快要结束了,抽一点时间来写一下,想一想自己就有成就感啊!!  2.关于任务跟踪管理系统项目中遇到的Windows服务以及Webservice的综合应用的问题. 大家好这是我第二次写博客 ,写的不好请大家多多谅解, 希望大家可以多多指正. 二:我稍微的整理了一下关于这个分布式定时器需求:1.根据任务跟踪管理系统中的数据库的AnswerSheet 表格中找到客户编

Asp.Net MVC中DropDownListFor的用法(转)

2016.03.04 扩展:如果 view中传入的是List<T>类型 怎么使用 DropList 既然是List<T> 那么我转化成 T  List<T>的第一个,最后一个不就是M吗? @Html.DropDownListFor(model=>model.First().Title, ViewData["Title"] as List<SelectListItem>, "标题", @"dropdown

ASP.NET MVC中使用窗体验证出现上下文的模型在数据库创建后发生更改,导致调试失败

在ASP.NET MVC中使用窗体验证.(首先要明白,验证逻辑是应该加在Model.View和Controller哪一个里面?由于Model的责任就是负责信息访问与商业逻辑验证的,所以我们把验证逻辑加在Model里面.) 第一步:引用下面这个命名空间 第二步:添加验证 第三步:启动调试,出现以下问题: 解决方法: 超链接中包含了解决这个问题的详细介绍,也就是通过Code First数据库迁移的方式让Entity Framework帮助我们自动调整数据库里面的架构. 解决这个问题最简单的方法就是将

关于asp.net MVC 中的TryUpdateModel方法

有比较才会有收货,有需求才会发现更多. 在传统的WebFormk开发工作中,我们常常会存在如下的代码块 //保存 protected void btnSubmit_Click(object sender, EventArgs e) { try { BLL.MoneyBll cun = new BLL.MoneyBll(); Model.Money m1 = new Model.Money(); m1.Commany = int.Parse(this.Commany.Text); m1.Count