gpt4 book ai didi

c# - 如何访问 ActionExecutingContext 中 ActionDescriptor 的 MethodInfo.ReturnType?

转载 作者:太空狗 更新时间:2023-10-29 20:02:39 35 4
gpt4 key购买 nike

我的应用程序上有一个 ActionFilterAttribute,用于在检测到用户未通过身份验证时重定向用户。在过滤器中,我想检测操作的 ReturnType 何时为 JsonResult。

作为解决方法,我最初创建了 IsJsonResult 的自定义属性,并使用该属性修饰了我的解决方案中的 JsonResult 方法。这有效,并在操作过滤器中实现如下:

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 对象内的调试器中。这是监 window 口中显示的路径:

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;
}

只要 Action 名称在 Controller 中是唯一的,就可以在 try block 中分配 returnType。但是如果 Controller 中有多个相同 Action 名称的实例,则会发生 AmbiguousMatchException。因此,在 catch block 中,我已将方法分配给一个集合。 使用 LINQ,我如何过滤来自 methodsInfoCollection 变量的值到通过 ActionExecutingContext 到达的操作?

下面是我研究过的一些文章,并使用了其中的一些想法。但我还没有弄清楚。

感谢您的帮助。

==============

更新到原始代码。这可行,但循环并不理想。

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 with a name of actionName.
MethodInfo[] methodInfoCollection = controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
foreach (MethodInfo methodInfo in methodInfoCollection)
{
if (methodInfo.ReturnType != null) {
if (methodInfo.ReturnType == typeof(ActionResult))
{
return false;
}
if (methodInfo.ReturnType == typeof(JsonResult))
{
return true;
}
}
}
}
return false;
}

请参阅下面 Reza Aghaei 的解决方案。他的解决方案完全消除了对单独方法的需求。

最佳答案

你可以使用

((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.ReturnType 

这是我试图检查返回类型是否为 JsonResult 的内容:

((ReflectedActionDescriptor)filterContext.ActionDescriptor).MethodInfo.ReturnType == typeof(JsonResult)

它为我的操作返回 true:

public JsonResult Index()
{
return Json(new { });
}

关于c# - 如何访问 ActionExecutingContext 中 ActionDescriptor 的 MethodInfo.ReturnType?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33089280/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com