zoukankan      html  css  js  c++  java
  • ActionInvoker

    ActionInvoker

    还是这张图:

    当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));
            }
     
     
     
  • 相关阅读:
    vim does not map customized key?
    再说vundle: 完全vim字符编程的四个必须插件
    centos7 没有iptables服务 file or directory? 用secureCRT登录centos?
    php基础语法-函数等
    windows下vmware10.0 安装centos7
    fedora23的firefox不能播放优酷视频?
    linux如何隐藏和显示所有窗口?
    fedora23忘记root密码怎么办??
    mouse scrollings and zooming operations in linux & windows are opposite
    windows 杂项
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3287191.html
Copyright © 2011-2022 走看看