C# 如何在ActionExecutingContext中访问ActionDescriptor的MethodInfo.ReturnType?
我的应用程序上有一个ActionFilterAttribute,用于在检测到用户未通过身份验证时重定向用户。在过滤器中,我想检测操作的ReturnType何时为JsonResult 作为一种解决方法,我最初创建了IsJsonResult的一个自定义属性,并用该属性修饰解决方案中的JsonResult方法。这将起作用,并在操作筛选器中实现,如下所示:C# 如何在ActionExecutingContext中访问ActionDescriptor的MethodInfo.ReturnType?,c#,asp.net,.net,asp.net-mvc,C#,Asp.net,.net,Asp.net Mvc,我的应用程序上有一个ActionFilterAttribute,用于在检测到用户未通过身份验证时重定向用户。在过滤器中,我想检测操作的ReturnType何时为JsonResult 作为一种解决方法,我最初创建了IsJsonResult的一个自定义属性,并用该属性修饰解决方案中的JsonResult方法。这将起作用,并在操作筛选器中实现,如下所示: public class CheckUser : ActionFilterAttribute { public override void
public class CheckUser : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext actionExecutingContext)
{
base.OnActionExecuting(actionExecutingContext);
object[] customAttributes = actionExecutingContext.ActionDescriptor.GetCustomAttributes(true);
bool isJsonResult = customAttributes.FirstOrDefault(a => a.GetType() == typeof(IsJsonResult)) != null;
if (isJsonResult)
{
return; // Don't perform any additional checks on JsonResult requests.
}
// Additional checking code omitted.
}
}
这是可行的,但我不喜欢在这个项目中装饰所有JsonResult操作。如果一个新的JsonResult被添加到项目中,并且我们忘记相应地装饰它,那么这很容易失败
此外,我可以看到名为“JsonResult”的ReturnType位于上面显示的actionExecutingContext对象内的调试器中。以下是“监视”窗口中显示的路径:
actionExecutingContext > ActionDescriptor > [System.Web.Mvc.ReflectedActionDescriptor] > MethodInfo > ReturnType > FullName
该FullName属性的值为“System.Web.Mvc.JsonResult”
因此,我似乎可以直接从actionExecutingContext对象中提取该值,并创建一个支持方法来返回bool指示符。为了实现这一点,下面是我编写的代码
private bool isReturnTypeJson(ActionExecutingContext actionExecutingContext)
{
string actionName = actionExecutingContext.ActionDescriptor.ActionName;
string controllerName = actionExecutingContext.ActionDescriptor.ControllerDescriptor.ControllerName;
Type controllerType = actionExecutingContext.Controller.GetType();
try
{
// Only effective when the actionName is not duplicated in the controller.
Type returnType = controllerType.GetMethod(actionName).ReturnType;
return (returnType.Name == "JsonResult");
}
catch (AmbiguousMatchException)
{
// Using LINQ, can I filter this collection to isolate just the methods
// that have the same name as the "actionName" variable above?
MethodInfo[] methodsInfoCollection = controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
// Attempted code from https://stackoverflow.com/questions/15283158/net-mvc-counting-action-methods-in-web-application
//var info = typeof(controllerType)
// .Assembly.GetTypes()
// .Where(t => typeof(Controller).IsAssignableFrom(t))
// .Where(t => t.Namespace.StartsWith("AwesomeProduct.Web"))
// .SelectMany(t => t.GetMethods(BindingFlags.Public | BindingFlags.Instance))
// .Where(m => typeof(ActionResult).IsAssignableFrom(m.ReturnType))
// .Where(m => !m.IsAbstract)
// .Where(m => m.GetCustomAttribute<NonActionAttribute>() == null);
}
return false;
}
见下面Reza Aghaei的解决方案。他的解决方案完全不需要单独的方法。您可以使用
((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.ReturnType
下面是我试图检查返回类型是否为:
对于我的行为,它返回真值:
public JsonResult Index()
{
return Json(new { });
}
谢谢@Reza Aghaei。filterContext.Result.GetType()==typeof(JsonResult);返回NullReferenceException。结果对象为空。你可能认为这会被填充,这是最直观的方法。是的,我检查后删除了我的评论;)我真的很感谢你的帮助。我已经更新了该方法以循环遍历集合。这是可行的,但并不理想。请参阅原始帖子中的调整。酷!让我来试一试。for.Net Dore-使用ControllerActionDescriptor而不是ReflectedActionDescriptor
((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.ReturnType == typeof(JsonResult)
public JsonResult Index()
{
return Json(new { });
}