【问题标题】:How do I get Http Verb attribute of an Action using reflection - ASP.NET Core?如何使用反射获取 Action 的 Http Verb 属性 - ASP.NET Core?
【发布时间】:2019-09-25 03:20:12
【问题描述】:

我正在尝试查找每个控制​​器 API 方法操作的 Http 动词(获取、发布、推送、删除等)。背景:尝试通过查看 http 操作(公司有将操作链接到所需的 ProducesResponseType StatusCode 的业务规则)为 Swagger 创建 ProducesResponseType 状态代码文档。

那么如何定位一个Controller的HTTP动作动词呢?

这似乎在调试中接近了,但是,这似乎不对。

foreach (ControllerModel controller in context.Result.Controllers)
        {
            foreach (ActionModel action in controller.Actions)
     controller.Actions.[0].ActionMethod.CustomAttributes[2]

推荐代码:

Net Core API: Make ProducesResponseType Global Parameter or Automate

ProduceResponseTypeModelProvider.cs

public class ProduceResponseTypeModelProvider : IApplicationModelProvider
{
    public int Order => 3;

    public void OnProvidersExecuted(ApplicationModelProviderContext context)
    {
    }

    public void OnProvidersExecuting(ApplicationModelProviderContext context)
    {
        foreach (ControllerModel controller in context.Result.Controllers)
        {
            foreach (ActionModel action in controller.Actions)
            {
                // I assume that all you actions type are Task<ActionResult<ReturnType>>

                Type returnType = action.ActionMethod.ReturnType.GenericTypeArguments[0].GetGenericArguments()[0];

                action.Filters.Add(new ProducesResponseTypeAttribute(StatusCodes.Status510NotExtended));
                action.Filters.Add(new ProducesResponseTypeAttribute(returnType, StatusCodes.Status200OK));
                action.Filters.Add(new ProducesResponseTypeAttribute(returnType, StatusCodes.Status500InternalServerError));
            }
        }
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...   
    services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ProduceResponseTypeModelProvider>());
    ...
}

是否有更简单的方法来检测控制器方法的动作动词?

以下问题适用于以前的 .Net。我们有 .Net Core 2.2。

How do I get http verb attribute of an action using refection - ASP.NET Web API

Detect if action is a POST or GET method

这些是常规 .Net 中的答案

之前的答案:

var methodInfo = MethodBase.GetCurrentMethod();
var attribute = methodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true).Cast<ActionMethodSelectorAttribute>().FirstOrDefault();

if (HttpContext.Request.HttpMethod == HttpMethod.Post.Method)
 {
 // The action is a post
 }

【问题讨论】:

    标签: c# .net asp.net-core .net-core asp.net-core-mvc


    【解决方案1】:

    我正在尝试获取相同的信息

    您可以尝试使用 Request.HttpContext.Request.Method

    它将http动词作为字符串返回,你可以用它来实例化一个System.Net.Http.HttpMethod对象

    var httpVerb = new HttpMethod(context.HttpContext.Request.Method);
    

    【讨论】:

    • 嗨,我刚刚尝试在 foreach 上面的 foreach 循环中使用 context.HttpContext.Request.Method 进行调试 (ActionModel action in controller.Actions) {,返回错误 context.HttpContext.Request.Method 错误 CS1061: “ApplicationModelProviderContext”不包含“HttpContext”的定义,并且找不到接受“ApplicationModelProviderContext”类型的第一个参数的可访问扩展方法“HttpContext”(您是否缺少 using 指令或程序集引用?){
    • 嗯,我以为你可以访问 HttpContext 但显然你不想从 ActionModel 类中获取它?
    • 您是否有权访问代码中的 ActionModel 对象?您是否尝试过使用属性 ActionMethod? docs.microsoft.com/en-us/dotnet/api/…
    • 我不抱歉。我想你需要做一些调试才能找出答案
    • 取决于此代码在应用程序生命周期中执行的时间,您根本不会有 HttpContext,因为它们是在对控制器进行调用时创建的,我可能错了,但我猜您的代码是在应用程序启动时运行
    【解决方案2】:

    您可以使用以下 sn-p 获取操作支持的 HTTP 动词。只有在使用属性时才会起作用。

    var verbs = action.Attributes.OfType<HttpMethodAttribute>().SelectMany(x => x.HttpMethods).Distinct();
    

    例子:

    public void OnProvidersExecuting(ApplicationModelProviderContext context)
    {
        foreach (ControllerModel controller in context.Result.Controllers)
        {
            foreach (ActionModel action in controller.Actions)
            {
                var verbs = action.Attributes.OfType<HttpMethodAttribute>().SelectMany(x => x.HttpMethods).Distinct();
    
                foreach (var verbItem in verbs)
                {
                    Console.WriteLine(verbItem);
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-30
      • 1970-01-01
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-05
      • 1970-01-01
      相关资源
      最近更新 更多