【问题标题】:filterContext for ActionResult in OnResultExecuted Method of ASP.NET MVCASP.NET MVC 的 OnResultExecuted 方法中 ActionResult 的 filterContext
【发布时间】:2013-07-25 08:06:59
【问题描述】:

我只需要从控制器操作返回类型为 ActionResult 的所有操作中过滤方法。 我正在从以下获取控制器名称和操作名称..

string originController = filterContext.RouteData.Values["controller"].ToString();
string originAction = filterContext.RouteData.Values["action"].ToString();

但是我怎样才能只过滤返回类型为 ActionResult 的方法呢?

【问题讨论】:

  • 你的意思是你只想要actions 将ActionResult 定义为方法签名中的返回类型?或者您还想要定义具体 ActionResults 的 actions(如 ViewResult)?
  • no.. 我只想要定义为 ActionResult 的操作。我可以从 filterContext 中获取这些操作吗?

标签: asp.net asp.net-mvc


【解决方案1】:

尝试使用这种代码来访问控制器、操作以及

  string originController = filterContext.RouteData.Values["controller"].ToString();
  string originAction = filterContext.RouteData.Values["action"].ToString();
  string originArea = String.Empty;
   if (filterContext.RouteData.DataTokens.ContainsKey("area"))
       originArea = filterContext.RouteData.DataTokens["area"].ToString();

【讨论】:

    【解决方案2】:

    在您的 Action Filter 中试试这个:

    var controllerActionDescriptor = filterContext.ActionDescriptor as System.Web.Mvc.ReflectedActionDescriptor;
    
    if (controllerActionDescriptor == null ||
        controllerActionDescriptor.MethodInfo.ReturnType != typeof(ActionResult))
            {
            return;
            }
    
    // if we got here then Action's return type is 'ActionResult'
    

    更新:

    由于您使用的是OnResultExecuted 方法,请尝试以下操作:

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        string originController = filterContext.RouteData.Values["controller"].ToString();
        string originAction = filterContext.RouteData.Values["action"].ToString();
    
        var actionType = filterContext.Controller.GetType().GetMethod(originAction).ReturnType;
    
        if (actionType != typeof(ActionResult))
            return;
    
        // if we got here then Action's return type is 'ActionResult'
    }
    

    更新:

    根据您的评论,如果有多个Action 同名(重载):

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        var actionName = filterContext.RouteData.Values["action"].ToString();
    
        var ctlr = filterContext.Controller as Controller;
        if (ctlr == null) return;
        var invoker = ctlr.ActionInvoker as ControllerActionInvoker;
        if (invoker == null) return;
    
        var invokerType = invoker.GetType();
        var getCtlrDescMethod = invokerType.GetMethod("GetControllerDescriptor", BindingFlags.NonPublic | BindingFlags.Instance);
        var ctlrDesc = getCtlrDescMethod.Invoke(invoker, new object[] {ctlr.ControllerContext}) as ControllerDescriptor;
    
        var findActionMethod = invokerType.GetMethod("FindAction", BindingFlags.NonPublic | BindingFlags.Instance);
        var actionDesc = findActionMethod.Invoke(invoker, new object[] { ctlr.ControllerContext, ctlrDesc, actionName }) as ReflectedActionDescriptor;
        if (actionDesc == null) return;
    
        if (actionDesc.MethodInfo.ReturnType == typeof (ActionResult))
        {
            // you're in
        }
    }
    

    【讨论】:

    • 这里filterContext属于ResultExecutedContext。我在 OnResultExecuted(ResultExecutedContext filterContext){} 方法中使用了它。所以我无法获得 filterContext.ActionDescriptor。
    • 我相应地修改了我的答案
    • 当我使用 OnResultExecuted 方法时。第二个工作正常。非常感谢@haim。
    • 我可以从这个 filterContext 中获取我的地区名称吗?
    • 使用filterContext.RouteData.DataTokens["area"]。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多