还是这张图:

当ControllerFactory生成Controller实例后,这时就需要使用ActionInvoker来选择调用一个合适的Action执行。ASP.NET MVC提供的基类Controller已经实现了ActionInvoker的功能。但是我们可以实现自定义的ActionInvoker来替代框架中提供的ActionInvoker。

首先一个ActionInvoker需要实现IActionInvoker接口:

public interface IActionInvoker
{
bool InvokeAction(ControllerContext controllerContext, string actionName) ;
}

InvokeAction参数有两个,其中controllerContext包含当前Controller信息和请求信息,而actionName则是用调用的action名。当函数找到一个合适的Action并成功调用时返回true,否则返回false。

那我们要怎样才能使用自定义的ActionInvoker呢,Controller类给我们提供了ActionInvoker属性,所以我们可以通过设置该属性让MVC使用我们的ActionInvoker:

    public class HomeController : Controller
{
public HomeController()
{
this.ActionInvoker = new MyActionInvoker();
} //....其他代码.....
}

MVC中内置的ActionInvoker

 上面也说了,基类Controller实现了ActionInvoker的功能,它使用的就是MVC内置的ActionInvoker-----ControllerActionInvoker。

一个方法要被ControllerActionInvoker当作一个Action需要满足以下条件:

  1.该方法的作用域必须为public

  2.该方法不能是静态方法

  3.该方法不能是Controller基类的方法

  4.该方法不能是构造函数

另外:如果方法是一个泛型方法,比且符合以上条件,则会在尝试调用的时候抛出一个异常

默认的,ControllerActionInvoker会将与actionName相同的方法名的方法作为Action,并调用。但是如果一个Controller中有多个同名的重载的方法时怎么办呢,我们可以使用ActionNameAttribute特性来设置Action别名:

    public class HomeController : Controller
{
[ActionName("Enumerate")]
public ActionResult List()
{
return View();
}
}

这样当我们请求/home/enumerate 时,调用的Action就是List,但当我们请求/home/list时,List将不会被调用,在这个例子中将返回404页面。

除了别名,ControllerActionInvoker还使用了action method selection(选择偏好)机制来处理如何选择多个同名的方法,来看下面的代码:

        [HttpGet]
public ViewResult MyAction(int? id)
{
return View(id);
} [HttpPost]
public ViewResult MyAction(Product product)
{
return View(product);
}

这个大家应该都很清楚了,当get请求时调用的是MyAction(int? id),而post请求时调用的是MyAction(Product product)。这就是action method selection。

我们可以创建自定义的Action Method选择器,来设定ControllerActionInvoker的选择偏好。

    public class ActionMethodSelectorAttribute : Attribute
{
public bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
return controllerContext.HttpContext.Request.IsLocal;
}
}

选择器需要有IsValidForRequest方法,当方法返回true时,表示符合偏好,会优先调用该方法。

ControllerActionInvoker未找到合适Action时的处理:

在这种情况下将会调用Controller的HandleUnknowAction方法,这个方法将会显示404页面,但是我们可以重写该方法以改变默认行为:

        protected override void HandleUnknownAction(string actionName)
{
Response.Write(string.Format("未发现你要找的Action: {0}", actionName));
}

ASP.NET MVC学习笔记-----ActionInvoker的更多相关文章

  1. ASP.NET MVC学习笔记-----Filter2

    ASP.NET MVC学习笔记-----Filter(2) 接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用 ...

  2. ASP.NET MVC学习笔记-----Filter

    ASP.NET MVC学习笔记-----Filter(1) Filter类型 接口 MVC的默认实现 Description Authorization IAuthorizationFilter Au ...

  3. ASP.NET MVC学习笔记-----Filter(2)

    接上篇ASP.NET MVC学习笔记-----Filter(1) Action Filter Action Filter可以基于任何目的使用,它需要实现IActionFilter接口: public ...

  4. ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现

    ASP.NET MVC 学习笔记-2.Razor语法   1.         表达式 表达式必须跟在“@”符号之后, 2.         代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...

  5. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  6. ASP.NET MVC 学习笔记(1)

    从头开始系统地学习ASP.NET MVC 为什么要学习ASP.NET MVC?原因很多,可以先来看一下最早的ASP.NET WebForm的一些缺点: 传说中面试经常要问到的ASP.NET WebFo ...

  7. 【转】ASP.NET MVC学习笔记-Controller的ActionResult

    1. 返回ViewResult public ActionResult Index()   {       ViewData["Message"] = "Welcome ...

  8. ASP.NET MVC学习笔记-----使用自定义的View Engine

    我们都知道在ASP.NET MVC中自带了Razor View Engine,Razor十分的强大,可以满足我们绝大部分的需要.但是ASP.NET MVC的高度可扩展性,使我们可以使用自定义的View ...

  9. ASP.NET MVC 学习笔记 1

    1. 什么是ASP.Net MVC ASP.Net MVC是一种开发Web应用程序的工具(is a web application development framework),采用Model-Vie ...

随机推荐

  1. [CareerCup] 10.7 Simplified Search Engine 简单的搜索引擎

    10.7 Imagine a web server for a simplified search engine. This system has 100 machines to respond to ...

  2. .NET MVC框架中控制器接收参数的四种方式

    1.通过路由中的配置的参数名字直接接收(要求:两者同名) routes.MapRoute(                 name: "Default",             ...

  3. abstract virtaul override new 及多态

    abstract abstract 修饰符可以和类.方法.属性.索引器及事件一起使用.在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类.标记为抽象或包含在抽象类中的成员必须通过从 ...

  4. 如何用Android Studio打多包名APK

    问题:项目中不同的分发渠道可能需要打包多种APK(同样的代码),包名可能是不一样的,如果一个一个修改包名重新编apk是很麻烦,可以参考下列步骤在Android Studio上操纵Gradle来打包不同 ...

  5. 2016 版 Laravel 系列入门教程(二)【最适合中国人的 Laravel 教程】

    本教程示例代码见: https://github.com/johnlui/Learn-Laravel-5 在任何地方卡住,最快的办法就是去看示例代码. 本篇文章中,我将跟宝宝们一起学习 Laravel ...

  6. 手工部署项目到tomcat

    正确的方法是,在eclipse里面的项目伤右键,然后Export,然后在弹出的框当中选择导出类型,这里选择web下面的WAR file,然后下一步,选择导出到哪里,然后把导出的war文件放到tomca ...

  7. logic标签用法

    logic  <logic:iterate> <% Dog dog1=new Dog(); dog1.setAge(2); dog1.setName("xiaoming& ...

  8. iOS彩票项目--第七天,初次读取json数据、KVC转模型技巧、运行时字典转模型以及初步对显示网页的操作并且跟踪标签

    一.初次读取json数据 二.KVC转模型技巧,这里的技巧主要解决的是字典中的key 与 模型中有的属性对应不起来的时候 的解决办法 <方法1> <方法2>运行时字典转模型,运 ...

  9. MongoDB的安装及配置

    MongoDB 是目前在IT行业非常流行的一种非关系型数据库(NoSql),其灵活的数据存储方式备受当前IT从业人员的青睐. Windows (1). 登录Mongodb官网点击下载 (2). 将zi ...

  10. Mysql常出现的问题

    1.mysql如何导入.txt文件?load data local infile 'D:\\data.txt' into table 表名 fields terminated by '\t';2.my ...