ASP.NET MVC3:有没有办法获取已解析操作的反射 MethodInfo?

发布于 2024-12-18 04:53:29 字数 605 浏览 1 评论 0原文

从自定义 HtmlHelper 扩展中,我想获取该操作的 MethodInfo

我知道我可以从以下位置获取控制器的类型和操作的字符串名称:

public static void MyHelper(this HtmlHelper helper)
{
  var controller = helper.ViewContext.Controller;
  var actionName = ViewContext.Controller.ValueProvider.GetValue("action").RawValue;
}

但我真的想要 MethodInfo 因为我想从动作方法。我不能只调用反射 .GetMethod(actionName); 因为通常有超过 1 个具有相同名称的操作(两个具有相同名称的操作,一个用于 http GET,一个用于 POST) 。

此时,我想我可能必须手动获取具有操作名称的所有方法,并运行 ViewContext.Controller.ValueProvider 中的所有信息,以查看哪些方法具有与中的值匹配的参数提供商,但我希望 MethodInfo 已经在某处可用......

From a custom HtmlHelper extension, I would like to get the MethodInfo for the action.

I know I can get the Type of the controller, and the string name of the action from:

public static void MyHelper(this HtmlHelper helper)
{
  var controller = helper.ViewContext.Controller;
  var actionName = ViewContext.Controller.ValueProvider.GetValue("action").RawValue;
}

But I really want the MethodInfo because I want to pull a custom Attribute off the action method. I can't just call reflection .GetMethod(actionName); because there is usually more than 1 with the same name (two actions with the same name, one for the http GET and one for the POST).

At this point I am thinking I might have to manually get all methods with the action name, and run through all the info in ViewContext.Controller.ValueProvider to see what method has parameters that match the values in the provider, but I am hoping the MethodInfo is already available somewhere...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

作死小能手 2024-12-25 04:53:29

确实没有简单的方法可以实现这一目标。通常,您可以使用自定义操作过滤器(不仅仅是任何类型的属性)来装饰控制器操作。因此,您可以让此自定义操作过滤器在当前 HttpContext 中注入一些信息,以便 HTML 帮助程序知道该视图是由用此自定义操作过滤器装饰的控制器操作提供的。

There's really no easy way to achieve that. Normally you decorate controller actions with custom action filters (not just any type of attributes). So you could have this custom action filter inject some information in the current HttpContext so that the HTML helper would know that the view was served from a controller action decorated with this custom action filter.

橘虞初梦 2024-12-25 04:53:29

获取当前 Action 的 MethodInfo 的一种方法是使用 StackTrace 和 RouteData 的组合。

您需要过滤掉所有不需要的 StackTrace 帧。

该代码将从嵌套的 Controller 类中运行,您可以在其中放置通用帮助程序,也可以将其放置在父 Controller 中

public FooController : BaseController
{
    [YourCustomAttribute]
    public ActionResult Edit(int id)
    {

       MethodInfo action = CurrentExecutingAction();

       // your code here, now you can get YourCustomAttribute Attribute for the Action

    }
}

public abstract class BaseController : Controller
{

    protected MethodInfo CurrentExecutingAction(Type type = null)
    {
        type = type ?? GetType();
        var rd = ControllerContext.RouteData;
        var currentAction = rd.GetRequiredString("action");

        StackTrace s = new StackTrace();
        return s.GetFrames()
            .Select(x => x.GetMethod())
            .Where(x => x is MethodInfo && x.Name == currentAction && x.DeclaringType.IsAssignableFrom(type))
            .Select(x => (MethodInfo) x)
            .LastOrDefault();
    }
}

One way to get the MethodInfo of the current Action is to use a combination of the StackTrace and the RouteData.

You need to filter out all the unwanted StackTrace Frames.

The code will work from nested Controller class where you put your common helpers, or you can place in parent Controller

public FooController : BaseController
{
    [YourCustomAttribute]
    public ActionResult Edit(int id)
    {

       MethodInfo action = CurrentExecutingAction();

       // your code here, now you can get YourCustomAttribute Attribute for the Action

    }
}

public abstract class BaseController : Controller
{

    protected MethodInfo CurrentExecutingAction(Type type = null)
    {
        type = type ?? GetType();
        var rd = ControllerContext.RouteData;
        var currentAction = rd.GetRequiredString("action");

        StackTrace s = new StackTrace();
        return s.GetFrames()
            .Select(x => x.GetMethod())
            .Where(x => x is MethodInfo && x.Name == currentAction && x.DeclaringType.IsAssignableFrom(type))
            .Select(x => (MethodInfo) x)
            .LastOrDefault();
    }
}
余生一个溪 2024-12-25 04:53:29

我已经回答了我自己的问题,与此非常相似。

给定一个实时控制器,以及另一个控制器和操作的名称,以及还有http方法(GET,POST),我开发了一种可以获取属性的方法。

像这样的东西:

public static Attribute[] GetAttributes(
    this Controller @this,
    string action = null,
    string controller = null,
    string method = "GET")

你这样称呼它:

var attrs = liveController
    .GetAttributes("anotherAction", "anotherController", "POST");

I have answered my own question, that is very similar to this.

Given a live controller, and the name of another controller and action, and also the http method (GET, POST), I have developed a method that can get the attributes.

Something like this:

public static Attribute[] GetAttributes(
    this Controller @this,
    string action = null,
    string controller = null,
    string method = "GET")

You call it like this:

var attrs = liveController
    .GetAttributes("anotherAction", "anotherController", "POST");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文