2

I am trying to find Http verb (Get, Post, Push, Delete, etc) of every Controller API Method action. Background: trying to create ProducesResponseType Status code documentation for Swagger, by reviewing http action (company has business rules linking action to required ProducesResponseType StatusCode).

So how to locate HTTP action verb of a Controller?

This seems to be coming close in debugging, however, this does not seem right.

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

Referring Code:

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>());
    ...
}

Is there simpler method to detect action verb of a Controller Method?

Questions below are for previous .Net. We have .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

These were answers in regular .Net

Answers before:

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
 }

2 Answers2

3

I am trying to get the same information

You ca try to use Request.HttpContext.Request.Method

It will return the http verb as a string and you can use it to instantiate a System.Net.Http.HttpMethod object with it

var httpVerb = new HttpMethod(context.HttpContext.Request.Method);
Cícero Neves
  • 401
  • 4
  • 13
  • Hi, I just tried debugging with context.HttpContext.Request.Method in the foreach loop above foreach (ActionModel action in controller.Actions) {, returning error context.HttpContext.Request.Method error CS1061: 'ApplicationModelProviderContext' does not contain a definition for 'HttpContext' and no accessible extension method 'HttpContext' accepting a first argument of type 'ApplicationModelProviderContext' could be found (are you missing a using directive or an assembly reference?) { –  Sep 26 '19 at 16:32
  • Hmm, I thought you had access to HttpContext but apparently you don't You want to get it from the ActionModel class? – Cícero Neves Sep 26 '19 at 16:42
  • do you have access to the ActionModel object in your code? Have you tried using the property ActionMethod? https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.applicationmodels.actionmodel.actionmethod?view=aspnetcore-2.2#Microsoft_AspNetCore_Mvc_ApplicationModels_ActionModel_ActionMethod – Cícero Neves Sep 26 '19 at 16:45
  • I don't sorry. I guess you will need to do some debugging to find out – Cícero Neves Sep 26 '19 at 16:50
  • Depending on when this code is executed in the app lifetime you won't have a HttpContext at all since those are created when a call is made to the controller I may be wrong but I guess your code is running when the application is starting – Cícero Neves Sep 26 '19 at 16:58
1

You can get HTTP verbs supported by actions with the following snippet. It will only work if attributes are used.

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

Example:

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);
            }
        }
    }
}
pavinan
  • 1,275
  • 1
  • 12
  • 23