Forum Discussion
ASP.NET Core 8 Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response.
I created a PATCH method in an ASP.NET Core Web API like this:
#region Patch
/// <summary>
/// Patch TableName by id.
/// </summary>
// PATCH BY ID: /TableName/patch/{id}
[HttpPatch("[action]/{id}", Name = "PatchTableNameById")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[SwaggerOperation(
Summary = "Patch Table Name by id",
Description = "This can be used to modify any table name record",
OperationId = "PatchTableNameById",
Tags = new[] { "Patch" }
)]
public async Task<IActionResult> Patch(string id, [FromBody] JsonPatchDocument<TableName> patchDoc)
{
if (patchDoc != null)
{
var tablename =
await context.TableName.SingleOrDefaultAsync(x => x.Id.ToString() == id);
if (tablename == null)
return NotFound();
patchDoc.ApplyTo(tablename);
context.Entry(tablename).State = EntityState.Modified;
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
await context.SaveChangesAsync();
return new ObjectResult(tablename);
}
else
{
return BadRequest(ModelState);
}
}This works perfectly fine when I call it using Postman or directly using Swagger. However in my Blazor client I get an error when it is called. I have tried using httpclient, RestSharp and now Flurl.
The error returned when using the Developer Tools console to review the log is:
Access to fetch at 'http://localhost:5259/SharedServices/Commands/TableName/patch/2bd4e0f3-974a-4794-bb63-b0ce00ba5147' from origin 'http://localhost:5265' has been blocked by CORS policy: Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response.
Here is my CORS policy in the Web API. It is called before anything else adding services.
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigins",
builder =>
{
builder.WithOrigins("http://localhost:56075", "http://localhost:5265",
"https://localhost:7235").AllowAnyHeader().WithMethods("PATCH");
});
});I have tried various combinations here including of allowing all methods, headers, and origins. In other words opening it wide up which isn't a great security tactic anyways.
Here is my client side code for the call.
public async Task Patch(string id, JsonPatchDocument<TableName> patchDoc)
{
var url = "http://localhost:5259/SharedServices/Commands/TableName/patch/" +
id;
var resultStr = await url.WithHeader("Content-Type", "application/json-patch+json").PatchJsonAsync(patchDoc)
.ReceiveString();
}I have tried about every online suggestion to fix this. One problem is there are a lack of issue reports for later versions of asp.net -- post addition of addCORS. I have tried various browsers thinking this maybe a browser issue but no luck there either. Is this possibly a bug in asp.net core cors? I am also using Steeltoe. Is it possible it is interfering with this?
Is there any way to turn off a preflight request or modify it?
I tried to use various clients such as httpclient, restsharp, flurl. Also tried using a PUT and got the same issue. I have also tried various browsers. The expected result is a successful unblocked call to my web api method.
Thanks for any help you can give!
2 Replies
- JaiminsoniCopper Contributor
I have tried to solve and summarise your issue for the PATCH method not being allowed in Blazor due to CORS restrictions, let me know if this helps.
Understanding the Issue:
- CORS (Cross-Origin Resource Sharing): A browser security mechanism that restricts web pages from making requests to a different domain than the one that served the page.
- Preflight Requests (for non-standard methods like PATCH): Browsers send an initial OPTIONS request to check allowed methods before making the actual PATCH request.
- Access-Control-Allow-Methods Header: The server must explicitly list PATCH in this response header to grant permission.
Resolving the Issue in Blazor:
Configure CORS in Startup.cs:
- Add the CORS middleware:
services.AddCors(options => { options.AddPolicy("AllowPATCH", builder => builder.WithOrigins("http://localhost:5000") // Adjust origins as needed .AllowAnyMethod() // Or explicitly list PATCH .AllowAnyHeader(); });- Apply the policy in the app's middleware pipeline:
app.UseCors("AllowPATCH");Enable CORS in ASP.NET Core Web API (if applicable):
- Use EnableCors attribute on controllers or actions:
[EnableCors("AllowPATCH")] [HttpPatch] public IActionResult PatchData() { // ... }- Ben_PierceCopper Contributor
JaiminsoniThank you for the helpful suggestions. This turned out to be a conflict with Steeltoe. When using AddAllActuators the Steeltoe code is adding it's own CORS policy overriding anything that I was setting up. When adding each actuator separately then it works. This was a tough one to solve. I was only able to do that by looking at the CORS policy collection and noticing there was an additional one above mine.