.Net,  Microsoft

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

Leave a Reply