• asp.net mvc Controller Factory


    此文摘要小妞之路,记录一下,方便自己查看学习

    Controller Factory控制器工厂:

    一般在实际项目中的用法:使用内置的Controller Factory,叫 DefaultControllerFactory。

    当 DefaultControllerFactory 类接收到一个 controller 实例的请求时,在 DefaultControllerFactory 类内部通过 GetControllerType 方法来获得 controller 的类型,然后把这个类型传递给 GetControllerInstance 方法以获得 controller 的实例。

    所以在 GetControllerInstance  方法中就需要有某个东西来创建 controller 实例,这个创建的过程就是 controller 被激活的过程。

    默认情况下 MVC 使用 DefaultControllerActivator 类来做 controller 的激活工作,它实现了 IControllerActivator 接口,该接口定义如下:

    public interface IControllerActivator { 
        IController Create(RequestContext requestContext, Type controllerType); 
    }



    内置的Action Invoker (ControllerActionInvoker)寻找的是和请求的 action 名称相同的 action 方法。比如路由系统提供的 action 值是 Index,那么 ControllerActionInvoker 将寻找一个名为 Index 的方法,如果找到了,它就用这个方法来处理请求。ControllerActionInvoker 允许我们对此行为进行调整,即可以通过使用 ActionName 特性对 action 使用别名,如下对 CustomerController 的 List action 方法使用 ActionName 特性:

    public class CustomerController : Controller {
        ...
        [ActionName("Enumerate")]
        public ViewResult List() {
            return View("Result", new Result {
                ControllerName = "Customer",
                ActionName = "List"
            });
        }
    }

    当请求 Enumerate Action 时,将会使用 List 方法来处理请求。下面是请求 /Customer/Enumerate 的结果:

    这时候对 /Customer/List 的请求则会无效,报“找不到资源”的错误,如下:

    使用 Action 方法别名有两个好处:一是可以使用非法的C#方法名来作为请求的 action 名,如 [ActionName("User-Registration")]。二是,如果你有两个功能不同的方法,有相同的参数相同的名称,但针对不同的HTTP请求(一个使用 [HttpGet],另一个使用 [HttpPost]),你可以给这两个方法不同的方法名,然后使用 [ActionName] 来指定相同的 action 请求名称。

    加一个LocalIndex 方法,并对它应用 “Index”别名,代码如下:

    public class CustomerController : Controller {
            
        public ViewResult Index() {
            return View("Result", new Result {
                ControllerName = "Customer",
                ActionName = "Index"
            });
        }
    
        [ActionName("Index")]
        public ViewResult LocalIndex() {
            return View("Result", new Result {
                ControllerName = "Customer",
                ActionName = "LocalIndex"
            });
        }

    这时如果请求 /Customer/Index,这两个 action 方法都会被匹配到而引发歧义问题,程序将会报错:

    我们来考虑这样一种情况:

    所有的 action 选择器都继承自 ActionMethodSelectorAttribute 类,这个类的定义如下:

    using System.Reflection; 
    
    namespace System.Web.Mvc { 
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
        public abstract class ActionMethodSelectorAttribute : Attribute { 
            public abstract bool IsValidForRequest(ControllerContext controllerContext,  MethodInfo methodInfo); 
        } 
    }

    同一个URL请求,在本地和远程请求的是不同的 action (如对于本地则绕过权限验证可能需要这么做)。那么自定义一个本地的 Action 选择器会是一个不错的选择。下面我们来实现这样一个功能的 Action 选择器:

    using System.Reflection;
    using System.Web.Mvc;
    
    namespace MvcApplication2.Infrastructure {
        public class LocalsAttribute : ActionMethodSelectorAttribute {
            public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
                return controllerContext.HttpContext.Request.IsLocal;
            }
        } 
    }

    这时候我们再对 LocalIndex 应用我们自定义的 Local 选择器:

    ...
    [Locals]//这样两个action名字相同时访问就不会有歧义了
    [ActionName("Index")]
    public ViewResult LocalIndex() {
        return View("Result", new Result {
            ControllerName = "Customer",
            ActionName = "Index"
        });
    }
    ...
  • 相关阅读:
    激活第一个CPU
    每CPU变量
    在 Vue中使用layui日历控件,标注重要日子
    手机号,银行卡断开方式
    下载文件流
    使用class关键字创建类组件、props参数
    class继承关键字extends和super
    用于判断文件是已什么结尾的
    flex一些属性
    类组件
  • 原文地址:https://www.cnblogs.com/wuyiran/p/6068557.html
Copyright © 2020-2023  润新知