ASP.NET MVC中OnResultExecuted方法中ActionResult的filterContext参数

8
我需要从控制器操作中仅筛选出返回类型为ActionResult的方法。我将从以下内容中获取控制器名称和操作名称...
string originController = filterContext.RouteData.Values["controller"].ToString();
string originAction = filterContext.RouteData.Values["action"].ToString();

但是我该如何过滤只有返回类型为ActionResult的方法?

你的意思是只想要那些在方法签名中定义了ActionResult作为返回类型的actions吗?还是也想要那些定义了具体的ActionResults(比如ViewResult)的actions - haim770
不,我只想要定义为ActionResult的操作。我能从filterContext中获取吗? - Naveen Katakam
2个回答

9
尝试使用以下代码来访问控制器、操作和其他内容:
  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();

7

在您的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。 - Naveen Katakam
我已经相应地修改了我的答案。 - haim770
我能从这个filterContext中获取我的区域名称吗? - Naveen Katakam
2
使用 filterContext.RouteData.DataTokens["area"] - haim770
当你有方法重载时,如何使用filterContext.Controller.GetType().GetMethod(originAction)呢? - Naveen Katakam
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接