转载于:http://www.cnblogs.com/wupeiqi/p/3570445.html

1、自定义一个HttpModule,并将其中的方法添加到HttpApplication相应的事件中!即:创建一个实现了IHttpmodule接口的类,并将配置WebConfig。
   在自定义的HttpModule中,可以将一个方法注册到HttpApplication的任意一个事件中,在之后执行HttpApplication一些列事件时,按照事件的顺序(事件又按照添加方法先后的顺序)执行注册在事件中的方法!

例:创建一个HttpModule(实现IHttpModule接口),并将一个方法注册到HttpApplication的BeginRequest(HttpAppliaction的第一个事件)事件中,即:由于该方法注册在HttpApplication第一个事件中,所有无论是合法还是非法的请求地址,该方法都会被执行。

利用HttpModule扩展知识,并通过NLog来完成写请求日志:源码下载

补充:在ASP.NET MVC中,css和js的请求是合并到一起发送给服务端的!

2、添加路由规则

3、自定义MapRoute方法

  第一步中MapRoute方法其实就是RouteCollection的扩展方法,我们也可以定义一个。

 微软定义的MapRoute方法
 自定义的MapRoute方法

注:在微软提供的MapRoute方法中可以看出,创建Route对象时,其构造函数的参数中有:new MvcRouteHandler。这个MvcRouteHandler用于之后创建HttpHandler对象,HttpHandler就是用来最后处理请求的!

4、自定义MvcRouteHandler
  即:实现IRouteHandler接口,MVC默认使用MvcRouteHandler来创建HttpHandler对象,用来处理请求!

 微软定义的MvcRouteHandler

  定义:我们自定义MvcRouteHandler时只需实现IRouteHandler接口,具体实现参照微软定义的MvcRouteHandler类

  使用:结合2中创建的自定义的MapRoute方法,将自己的MvcRouteHandler对象添加到Route对象中!

第2、3、4步骤示例:源码下载

5、自定义MvcHandler

  对于微软的类MvcHandler其实就是一个HttpHandler(实现IHttpHandler接口),在MVC整个处理机制中,MvcHandler接收到请求并激活Controller、执行Action、View的呈现 等。MvcHandler是执行MvcRouteHandler的GetHttpHandler方法得到的!

在第2、3、4步骤的基础上,使用自定义MvcHandler处理请求:源码下载

6、自定义ControllerFactory

  ControllerFactory用于Controller的激活,也就是创建Controller对象。对于MVC,这个ControllerFactiory是通过ControllerBuilder.Current.GetControllerFactory();得到,默认得到的ControllerFactory是DefaultControllerFactory对象!

 MvcHandler
 ControllerBuilder

  上述两个类,MvcHandler中通过GetControllerFactory获取的就是通过ControllerBuilder的SetControllerFactory方法设置ControllerFactory(没有设置时,默认是DefaultControllerFactory)。这就是我们创建自定义ControllerFactory的入口。

  上面就是简单的列举了执行流程,不再进行过多的介绍,因为在实际开发中,一般不会使用自定义一个ControllerFactory,因为其中包含的功能,我们自己来定义时可能考虑的不够全面,如果项目需求必须使用的话,要细看微软在DefaultControllerFactory中各种功能!!!既然不用自定义的ContollerFactory,那么就只能用DefaultControllerFactory了,DefaultControllerFactory中也有扩展点让我们利用,就是下面第7中介绍的!

7、自定义ControllerActivator

  在6中我们讲到,DefaultControllerFactory用于创建Controller对象,而这个ControllerActivator实际上就是DefaultControllerFactory中负责创建Controller对象“组件”。默认情况下,使用的是微软提供的DefaultControllerActivator(DefaultControllerFactory的构造函数中设置)。

 微软:DefaultControllerActivator

自定义:
  定义:实现IControllerActivator接口
  使用:通过DefaultControllerFactory的构造函数将自定义ControllerActivator “注入”。
           在Global.asax中添加 ---> ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory(new MyControllerActivator()));

  应用场景1:在Controller激活之前做一些操作
  应用场景2:通过Controller的构造函数实现在创建Controller对象时“注入”值!因为默认情况下,激活Controller的时候是执行的其无参数构造函数!

应用场景2+依赖注入:源码下载

8、自定义ActionInvoker

  ActionInvoker用于去执行被请求的Action方法,这过程中包含了 View的呈现 以及执行各种应用在Action上的特性(HttpMethod、Filter、DisplayName...等),由于功能忒多,所以不到不得已也不建议自己重写ActionInvoker。不过如果项目需要,可以继承微软默认使用的 ControllerActionInvoker,从而在已有功能的基础上添加自己的需要的功能!

自定义:
  定义:实现IActionInvoker接口
  使用:在Controller的构造函数中设置自己的ActionInvoker

仅第8步骤示例:源码下载

下面的9、10、11讲的是和特性相关的扩展,所以在介绍它们之前先来复习下MVC中使用的特性种类和处理流程:

  种类:

    ActionNameSelectorAttribute 
        ActionNameAttribute
    ActionMethodSelectorAttribute
        AcceptVerbsAttribute
        HttpDeleteAttribute
        HttpGetAttribute
        HttpPostAttribute
        HttpPutAttribute
        NonActionAttribute
        HttpHeadAttribute
        HttpOptionsAttribute
        HttpPatchAttribute //灰色字体的是MVC4中新增的!
    FilterAttribute、IActionFilter或IAuthorizationFilter或IExceptionFilter或IResultFilter
        自定义类去实现相应接口

  处理流程:Contrller激活之后,要从Controller对象的方法中查找当前请求的Action,那么其流程为 ----> 先获取所有应用了ActionName特性并且ActionName特性设置的name=当前请求的Action名称(将符合条件的添加的List<MethodInfo>中),之后去获取所有没有应用ActionName特性的方法并且方法名=当前请求的Action名称,(再将符合条件的添加到之前创建的List<MethodInfo>尾部);再之后对符合名称条件的Action方法集合处理,判断应用在Action方法上的NonAction、AcceptVerbs、HttpGet等6个特性(MVC4有9个特性)是否和当前请求一致;再再之后执行第三种过滤器,需要自己定义且实现接口,并应用在Action上,他们的执行顺序为:【IAuthorizationFilter】--->【IActionFilter】--->【Action方法内部代码】--->【IResultFilter】,如果上述4个过程中有异常抛出,则执行【IExceptionFilter】。个更多处理流程的介绍请猛击这里

9、继承自ActionNameSelectorAttribute 的特性:ActionNameAttribute

  用于对Controller类中Action方法的重命名!当请求指定的 Controller/Action时,将用重命名后的名称去和请求的Action名称匹配。

 微软定义的ActionNameAttribute

使用:

  如上设置ActionName后,当请求Home/Index就提示找不到无法找到资源,当请求Home/OtherName时,就会去执行这个Index方法!

10、继承自ActionMethodSelectorAttribute的特性:AcceptVerbsAttribute...等

  该类特性中仅NonAction用于指示该方法不作为Action来使用,而其他的5个则都是用于判断Http请求的方式!

  HttpGet    只有客户端发送的是Get请求才能执行该Action
  HttpPost      只有客户端发送的是Post请求才能执行该Action ...Post请求
  HttpDelete     只有客户端发送的是Delete请求才能执行该Action
  HttpPut    只有客户端发送的是Put请求才能执行该Action
  AcceptVerbs  参数是一个枚举(Get、Post等),其功能和以上四个相同
注:由于以上的特性类都应用了: [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)],所以这些特性只能应用在Action方法上并且每个只能使用一个。

使用:仅列出HttpPost,其他使用方法相同,不再列举。

  如上所示,只有客户端发送的是Post请求时,才能执行该Action。

11、FilterAttribute、IActionFilter或IAuthorizationFilter或IExceptionFilter或IResultFilter

  该类过滤器执行的顺序为:【IAuthorizationFilter】--->【IActionFilter】--->【Action方法内部代码】--->【IResultFilter】,如果上述4个过程中有异常抛出,则执行【IExceptionFilter】。
  由于FilterAttribute类应用了 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)],所以该类特性可以应用在 类 或 方法 上且默认也只能使用一次,如果想要使用多个同样的特性,可以在自定义的特性上添加: [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]即可。
  该类过滤器有 4 种添加方式:以特性应用在Action方法上、以特性应用在Controller类上、Global.asax文件中RegisterGlobalFilters方法中添加、在Controller中重写各个过滤器方法(因为Controller类都实现各个接口),区别是这4种方式的作用域不同!

  11-1、IAuthorizationFilter

  微软定义的该类过滤器有:ChildActionOnlyAttribute、AuthorizeAttribute,可以参考这两个类来定义自己的IAuthorizationFilter过滤器。

 ChildActionOnlyAttribute
 AuthorizeAttribute

  11-2、IActionFilter--->Action方法内部代码--->IResultFilter

  IActionFilter有两个方法OnActionExecuting(在执行操作方法之前调用)、OnActionExecuted(在执行操作方法后调用)。IResultFilter也有两个方法OnResultExecuting(在操作结果执行之前调用)、OnResultExecuted(在操作结果执行后调用),由于这里说的【在执行操作方法后调用】和【在操作结果执行之前调用】容易造成混淆,这里我们就来确定的说明一下其执行流程为:OnActionExecuting--->OnActionExecuted--->Action方法内的代码--->OnResultExecuting--->OnResultExecuted

  11-3、IExceptionFilter

  Action方法上应用该特性后,如果执行:IAuthorizationFilter过滤器、IActionFilter过滤器、Action方法内的代码、IResultFilter过滤器,抛出了异常,则会执行该方法!(只要出现有异常,则不会再继续往下执行后面的过滤器)

1
2
3
4
5
6
7
8
public class MyExceptionFilter : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        //如果filterContext.ExceptionHandled = false(默认),则直接抛出异常。(filterContext.ExceptionHandled表示是否已经处理异常)
        //否则,为filterContext.Result赋一个ActionResult,使用这个ActionResult执行View的呈现!
    }
}

12、自定义ActionResult

  自定义一个ActionResult,只需要继承抽象类ActionResult,并实现其抽象方法ExecuteResult即可!微软中已经定义很多ActionResult(EmptyResult、ContentResult、JsonResult、ViewResult等)。

使用时,只需要创建一个MyActionResult对象并让Action方法将其返回,或者在第11中任何一个过滤器中创建一个MyActionResult对象并赋值给filterContext.Result。下面是两个使用MyActionResult的例子:

定义一个生成验证码的VerifyCodeResult示例:源码下载

13、自定义HtmlHelper

  在 .cshtml 文件中 使用的 @Html.TextBox(...)等,他们都是HtmlHelper类的扩展方法(定义在System.Web.Mvc.Html.InputExtensions中),更多关于@Html.xxx()方法的详细介绍请:猛击这里

使用HtmlHelper扩展开发一个【分页功能】:源码下载

14、自定义ModelBinder

15、自定义ValueProvider

  在学习 第14、15 扩展点之前,先来思考下! 在我们定义的Action方法中,他们的参数值是如何得到的呢? 
  答:通过这第14、15个扩展点会让你对参数值的得到有个清楚的认识!在我的《白话学习MVC系列》的模型绑定一篇中已经做了详细的介绍!【猛击这里】

16个ASP.NET MVC扩展点【附源码】的更多相关文章

  1. 17+个ASP.NET MVC扩展点,含源码{转}

    1.自定义一个HttpModule,并将其中的方法添加到HttpApplication相应的事件中!即:创建一个实现了IHttpmodule接口的类,并将配置WebConfig.在自定义的HttpMo ...

  2. asp.net MVC 模拟实现与源码分析

    前言 本文流程#1: 从一个空项目->模拟实现一个从/Home/Test形式的URL敲入->后台逻辑处理->传入后台model参数->调用razor引擎->前台展示 涉及 ...

  3. WinDBg定位asp.net mvc项目异常崩溃源码位置

    项目介绍:asp.net mvc + angular +iis(windows)+windows server 系统莫名崩溃 最近有个系统默认奇妙崩溃50x,服务整体变成无响应,当运维告知我只有重启应 ...

  4. ASP.NET MVC 5.0 参考源码索引

    http://www.projky.com/asp.netmvc/5.0/Microsoft/AspNet/Mvc/Facebook/FacebookAppSettingKeys.cs.htmlhtt ...

  5. ASP.NET MVC 4.0 参考源码索引

    http://www.projky.com/asp.netmvc/4.0/Microsoft/AspNet/Mvc/Facebook/FacebookAppSettingKeys.cs.htmlhtt ...

  6. ASP.NET MVC 3.0 参考源码索引

    http://www.projky.com/asp.netmvc/3.0/Microsoft/Internal/Web/Utils/CommonResources.cs.htmlhttp://www. ...

  7. ASP.NET MVC 2.0 参考源码索引

    http://www.projky.com/asp.netmvc/2.0/System/Web/Mvc/AcceptVerbsAttribute.cs.htmlhttp://www.projky.co ...

  8. ASP.NET MVC 1.0 参考源码索引

    http://www.projky.com/asp.netmvc/1.0/System/Web/Mvc/AcceptVerbsAttribute.cs.htmlhttp://www.projky.co ...

  9. Asp.Net.Mvc+MEF+EF 项目 ,源码在GitHub ..希望对大家有所帮助

    自己开源的 一个 Asp.Net + MEF+ EF 的 项目 . 供大家学习和使用, 点击进入GitHub

随机推荐

  1. 洛谷 P1373 小a和uim之大逃离 (差值型dp总结)

    这道题和多米诺骨牌那道题很像 ,都是涉及到差值的问题. 这道题是二维的,同时要取模. 这种题,因为当前的决策有后效性,会影响到差值,所以直接把 差值作为维度,然后计算答案的时候把差值为0的加起来就行了 ...

  2. 部署OGG时字符集转换问题--oracle to oracle已验证,其他异构环境应当也适用

    之前在安装OGG总是遇到字符集问题,尤其是多源端对一个目标端时,源端字符集不同,导致出现字符集问题 无法同步数据,查阅了大量的园子资料,都说要设置复制或抽取进程中SETENV (NLS_LANG=AM ...

  3. 操作指定文件格式的10个Perl CPAN模块

    在Perl开发中,非常可能会碰到一些不同格式的文件--XML.PDF.CSV及RSS文件等,和一些不同的二进制数据格式.Perl应用程序须要操作这些文件,对它们进行读写. 此时.能够求助于全面Perl ...

  4. node tail 日志服务

    var http = require('http'), ,spawn = require('child_process').spawn function onRequest(req, res) { v ...

  5. Linux下安装Mysql(RPM安装)

    一.去官网下载本次安装须要的mysql版本号.我们须要安装的是5.1版本号的且centos系统是64位的.所下面载的是MySQL-community-5.1.73-1.rhel5.x86_64.rpm ...

  6. Linux/UNIX线程(1)

    线程(1) 本文将介绍怎样使用多个控制线程在单个进程环境中运行多个任务. 一个进程中的全部线程都能够訪问该进程的组成部件(如文件描写叙述符和内存). 线程包含了表示进程内运行环境必须的信息,当中包含进 ...

  7. iOS代码添加视图约束

    项目要做这样一个效果的启动页. 考虑到版本号是会不断变更的,因此采用动画效果启动页,让版本号动态加载iOS启动页动画效果 - 简书 考虑到屏幕适配问题,因此采用代码对视图添加约束.在添加约束的过程中遇 ...

  8. [转]Python UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 的解决办法

    UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 的解决办法 python在安装时,默认的编码是ascii,当 ...

  9. <a>标签是什么意思 怎么使用?

    转自:https://www.imooc.com/qadetail/190881 (1) a标签的作用:超链接,用于跳转到别的网页. (2) a标签的用法:<a href="网址&qu ...

  10. 36.创建模板mylist

    node.h #pragma once //创建模板 template <class T> class Node { public: T t;//数据 Node *pNext;//指针域 ...