I am using dotnet 6 Web API. I have a consumer that can only use POST or GET. So I need to redirect their POST request to my PUT endpoint. I am trying to implement HttpMethodOverrideMiddleware
but can't get it to work.
Here is my program.cs
:
namespace middlewareTesting
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseHttpMethodOverride();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
}
}
}
And here is my controller:
using Microsoft.AspNetCore.Mvc;
namespace middlewareTesting.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IActionResult Get()
{
return Ok("GET WAS HIT");
}
[HttpPost(Name = "PostWeatherForecast")]
public IActionResult Post()
{
return Ok("POST WAS HIT");
}
[HttpPut(Name = "PutWeatherForecast")]
public IActionResult Put()
{
return Ok("PUT WAS HIT");
}
}
}
When I use Postman and specify a header with a key of X-HTTP-Method-Override
and a value of PUT
, it doesn't hit the PUT method. It hits the Post method.
However, if I set a breakpoint and inspect the Request
object it looks like it changed the method to PUT.
{Microsoft.AspNetCore.Http.DefaultHttpRequest}
Body: {Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestStream}
BodyReader: {Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestPipeReader}
ContentLength: 147
ContentType: "application/json"
Cookies: {Microsoft.AspNetCore.Http.RequestCookieCollection}
Form: '((Microsoft.AspNetCore.Http.DefaultHttpRequest)Request).Form' threw an exception of type 'System.InvalidOperationException'
HasFormContentType: false
Headers: {Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpRequestHeaders}
Host: {localhost:7188}
HttpContext: {Microsoft.AspNetCore.Http.DefaultHttpContext}
IsHttps: true
Method: "PUT"
Path: {/WeatherForecast}
PathBase: {}
Protocol: "HTTP/1.1"
Query: {Microsoft.AspNetCore.Http.QueryCollection}
QueryString: {}
RouteValues: {Microsoft.AspNetCore.Routing.RouteValueDictionary}
Scheme: "https"
Is this behavior expected? Do I need to do anything in my POST method? Do I have to do anything else to get this to work?
CodePudding user response:
Can't explain why but adding UseRouting
after the UseHttpMethodOverride
made it work for me:
app.UseHttpMethodOverride();
app.UseRouting();