Configure Allowed HTTP Methods Globally in ASP.NET Core Web API

How to Configure the Allowed HTTP Methods Globally in ASP.NET Core Web API

In this article, I will discuss How to Configure the Allowed HTTP Methods Globally in ASP.NET Core Web API Application with Examples. Please read our previous article discussing How to Return 405 Not Found HTTP Status Code in ASP.NET Core Web API with Examples.

How to Configure the Allowed HTTP Methods Globally in ASP.NET Core Web API

Configuring the allowed HTTP methods globally in an ASP.NET Core Web API project is essential for defining which HTTP request methods (such as GET, POST, PUT, DELETE) your application will accept. This configuration can help improve the security and manageability of your API by ensuring that only intended methods are handled by your application.

There are several approaches to achieve this configuration, each with advantages and use cases. Below are steps to configure allowed HTTP methods globally using Custom Middleware and Custom Action Filter:

Using Custom Middleware to Configure Allowed HTTP Methods Globally

You can create custom middleware to check the HTTP method of incoming requests and allow or block them based on your requirements.

Create a Middleware Class

First, create a middleware class that inspects the HTTP method of each request. So, create a class file named HttpMethodMiddleware.cs and copy and paste the following code. The following HttpMethodMiddleware class is a custom middleware component. It is used to filter incoming HTTP requests based on the HTTP method (e.g., GET, POST, PUT, DELETE) and only to allow requests that use specified methods. Requests that use disallowed methods are rejected with a “405 Method Not Allowed” status code.

using System.Text.Json;

namespace ReturnTypeAndStatusCodes.Models
{
    public class HttpMethodMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly string[] _allowedMethods;

        public HttpMethodMiddleware(RequestDelegate next, string[] allowedMethods)
        {
            _next = next;
            _allowedMethods = allowedMethods;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            if (!_allowedMethods.Contains(context.Request.Method))
            {
                context.Response.StatusCode = StatusCodes.Status405MethodNotAllowed;
                context.Response.ContentType = "application/json";
                var customResponse = new
                {
                    Code = 405,
                    Message = "HTTP Method not allowed"
                };
                var responseJson = JsonSerializer.Serialize(customResponse);
                await context.Response.WriteAsync(responseJson);

                return; //Short Circuiting the Request Processing Pipeline 
            }

            await _next(context);
        }
    }
}
In the above example,
  • RequestDelegate _next: This is a function delegate that represents the next middleware in the ASP.NET Core request processing pipeline. Middleware components are called in sequence, and each one can choose to pass the request to the next component by calling _next.
  • string[] _allowedMethods: This array holds the list of HTTP methods allowed by this middleware. Any request that does not use one of these methods will be rejected.
  • Constructor: The HttpMethodMiddleware Constructor initializes the middleware with the next delegate to call in the pipeline and the list of allowed HTTP methods.
  • public async Task InvokeAsync(HttpContext context): This method is called by the ASP.NET Core runtime to process an HTTP request. It takes an HttpContext object as a parameter, which provides information about the incoming request and a way to modify the outgoing response.
  • if (!_allowedMethods.Contains(context.Request.Method)): This line checks if the HTTP method of the incoming request is in the list of allowed methods. context.Request.Method returns the HTTP method of the request (e.g., “GET”, “POST”, “PUT”, “DELETE”).
  • context.Response.StatusCode = StatusCodes.Status405MethodNotAllowed;: If the request’s method is not allowed, this line sets the response status code to “405 Method Not Allowed”. This tells the client that the method used in the request is not supported by the resource.
  • context.Response.ContentType = “application/json”;: This statement sets the response’s ContentType to application/json. This is important for informing the client that the response body is in JSON format.
  • It then writes a JSON string to the response body with a custom error message indicating that the HTTP method used in the request is not allowed. This is done using context.Response.WriteAsync(…), which asynchronously writes the specified data to the HTTP response body.
  • return;: This statement exits the method early, preventing the request from being passed further down the middleware pipeline.
  • await _next(context);: If the request’s method is allowed, this line passes the request to the next middleware in the pipeline for further processing.
Register the Middleware

After creating the middleware, you need to register it in the Program class. It’s important to add it at the right point in the middleware pipeline to ensure it executes before executing any action method. Here, we need to specify which HTTP methods are allowed globally.

var allowedMethods = new[] { "GET", "POST", "DELETE" };

// Use a lambda to manually instantiate the middleware
app.Use(async (context, next) =>
{
    var middleware = new HttpMethodMiddleware(next, allowedMethods);
    await middleware.InvokeAsync(context);
});
Creating Controller:

Create the following controller. As you can see, we have created the following controller with five different HTTP Methods.

using Microsoft.AspNetCore.Mvc;

namespace ReturnTypeAndStatusCodes.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SampleController : ControllerBase
    {
        // This action only supports GET method
        [HttpGet]
        public IActionResult GetAction()
        {
            return Ok("GetAction Data processed");
        }

        // This action only supports POST method
        [HttpPost]
        public IActionResult PostAction()
        {
            return Ok("PostAction Data Processed");
        }

        // This action only supports PUT method
        [HttpPut]
        public IActionResult PutAction()
        {
            return Ok("PutAction Data processed");
        }

        // This action only supports PUT method
        [HttpPatch]
        public IActionResult PatchAction()
        {
            return Ok("PatchAction Data processed");
        }

        // This action only supports DELETE method
        [HttpDelete]
        public IActionResult DeleteAction()
        {
            return Ok("DeleteAction Data processed");
        }
    }
}

Now, run the application and access the above endpoints. You will see that GET, POST, and DELETE requests are accepted, as shown in the below image:

How to Configure the Allowed HTTP Methods Globally in ASP.NET Core Web API

On the other hand, PUT and PATCH requests are going to return 405 Method Not Allowed responses, as shown in the image below.

How to Configure the Allowed HTTP Methods Globally in ASP.NET Core Web API

Global Action Filter to Handle 405 Status Code

You can create a global action filter that checks the HTTP method of incoming requests and decides whether to allow or reject them. This filter can then be added to the MVC options in the Program.cs. So, create a class file named HttpMethodFilter.cs and copy and paste the following code.

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc;

namespace ReturnTypeAndStatusCodes.Models
{
    public class HttpMethodFilter : IActionFilter
    {
        private readonly string[] _allowedMethods;

        public HttpMethodFilter(string[] allowedMethods)
        {
            _allowedMethods = allowedMethods;
        }

        public void OnActionExecuting(ActionExecutingContext context)
        {
            if (!_allowedMethods.Contains(context.HttpContext.Request.Method))
            {
                var customResponse = new
                {
                    Code = 405,
                    Message = "HTTP Method not allowed"
                };

                context.Result = new ObjectResult(customResponse)
                {
                    StatusCode = 405
                };
            }
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
        }
    }
}
In this example,
  • IActionFilter Interface: Implementing this interface allows the class to act as an action filter. Action filters in ASP.NET Core can execute code before and after an action method runs, providing a powerful way to modify the execution flow of action methods.
  • string[] _allowedMethods: This array stores the HTTP methods (e.g., GET, POST, PUT, DELETE) permitted by this filter. Any request that doesn’t match these methods will be blocked.
  • Constructor: The constructor receives an array of allowed HTTP methods and initializes the filter with these values. When you apply the filter globally in our Program.cs class file, we need to specify which methods are allowed for our application.
  • OnActionExecuting Method: This method is called before the action method executes. It takes an ActionExecutingContext object as a parameter, which provides information about the current request and the action being executed. The method checks if the current request’s HTTP method is in the _allowedMethods list. If not, it sets the action result to a StatusCode with a status code of 405 (Method Not Allowed), effectively stopping the action from executing.
  • OnActionExecuted Method: This method is called after the action method executes. In this implementation, it’s intentionally left empty because the filter’s purpose is to validate the HTTP method before the action executes. However, this method can be used for post-action execution logic if needed.
Registering the Filter Globally:

Please add the following code to the Program.cs class file. As you can see, while adding the filter, we are specifying which HTTP methods are allowed for our application.

builder.Services.AddControllers(options =>
{
    options.Filters.Add(new HttpMethodFilter(new[] { "GET", "POST", "DELETE" }));
});

With the above changes in place, run the application and test each endpoint, and it should work as expected in the previous example.

In the next article, I will discuss How to Return 500 Internal Server Error HTTP Status Code in ASP.NET Core Web API with Examples. In this article, I try to explain How to Configure the Allowed HTTP Methods Globally in ASP.NET Core Web API with Examples, and I hope you enjoy this article on “How to Configure the Allowed HTTP Methods Globally in ASP.NET Core Web API”.

Leave a Reply

Your email address will not be published. Required fields are marked *