Dotnet 6 API with a HttpDelete and that 405 Method not allowed error
As we can tell from the title of the Post, we are going to talk about figuring out why in a client app one gets a Http Status code of 405 (Method Not Allowed).
When does this happen? Usually when a http request does a http PUT or DELETE. Yet, when one uses Swagger (openAPI) or Postman to directly call the same API Delete or Put, it works! This is starting to feel like a CORS issue, right? Read On ==>
So 405! Indeed looking at the surface of what is going on, one thinks Ah! CORS is at it again! Absolutely, this is what it feels like. After all, a Swagger/Postman GET/DELETE call under the same http domain works. But the moment one moves to a Client App coming in from a different domain (i.e. a different port on localhost, because different ports are also considered a different domain in terms of CORS), the Http PUT/DELETE stops working and throws a 405.
We are using VS2022 with Dotnet 6.0.100-rc.2.21505.57 (so the latest VS2022 and Dotnet RC 6 as of the writing of this post)
Wow… let’s step into how to rein in CORS…. We start in the API project in the Startup class.
In Configure Services =>
services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder .AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod() .WithMethods("GET","PUT","DELETE","POST","PATCH") //not really necessary when AllowAnyMethods is used. ); });
We build a CORS policy (yes one can remove the .WithMethods clause)
And of course we add in the Configure method =>
app.UseRouting(); app.UseCors("CorsPolicy");
And everything is right with the world… Let’s do a Delete in a client app. Meaning we are doing HttpClient Delete to a rest url that contains the id:
Yeap a hard 405… What the what What?
After digging through lots of readings on the topic of CORS 405 PUT/DELETE, DotNet 6 issues (with not much luck), I stepped upon the answer with a bit of thinking about the problem….
In my Controller we have this as the delete method header =>
[HttpDelete("id")] public async Task<IActionResult> Delete(int id) { ...
Seems simple enough, it works in the Swagger interface for testing the API. I validated that the client is using and passing the correct url and id. WHAT!?
Look closely at the [HttpDelete… tag. Notice anything? If one said, “Duh, ScottGeek- you need to wrap the “id” within {}” then YEAP!
That would be the issue. The real question is why does this seem work in the Swagger UI for the api but not in a app using HttpClient?
I have absolutely no idea why (yes I could get Fiddler out and start digging deep, nope) In this case what seems like a CORS acting up issue (405 on a cross domain request), yeah it’s not, or is it? This seems to be a bug somewhere, I suspect, in the OpenAPI (swagger) bits. Why in the OpenAPI? because it should reflect the same 405 when the API Method tag is not 100% correct.
But let’s not just pick on OpenAPI. The fact that DotNet 6 allows both [HttpDelete(“id”)] and [HttpDelete(“{id}”)] without issuing some kind of build blowup or at least a green squiggle on the one that is in error… well I give it to ya… feels like a bug.
Put the {} around the id and….
Also, don’t forget to check one’s HttpPut as well…
~SG