我在 ASP.NET Core Web API 中创建了一个 PATCH 方法,如下所示:
#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);
}
}
当我使用 Postman 或直接使用 Swagger 调用它时,效果非常好。但是,在我的 Blazor 客户端中,调用它时出现错误。我尝试过只使用 httpclient、RestSharp,现在又尝试使用 Flurl。
使用开发者工具控制台查看日志时返回的错误为:
从源“http://localhost:5265”获取“http://localhost:5259/SharedServices/Commands/TableName/patch/2bd4e0f3-974a-4794-bb63-b0ce00ba5147”的访问已被 CORS 策略阻止:预检响应中的 Access-Control-Allow-Methods 不允许方法 PATCH。
这是我在 Web API 中的 CORS 策略。它在添加服务之前被调用。
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigins",
builder =>
{
builder.WithOrigins("http://localhost:56075", "http://localhost:5265",
"https://localhost:7235").AllowAnyHeader().WithMethods("PATCH");
});
});
我在这里尝试了各种组合,包括允许所有方法、标头和来源。换句话说,打开它无论如何都不是一个很好的安全策略。
这是我的调用客户端代码。
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();
}
我已经尝试了所有在线建议来解决这个问题。一个问题是缺少针对更高版本的 ASP.NET 的问题报告——添加了 addCORS 后。我尝试过各种浏览器,认为这可能是浏览器问题,但也没有运气。这可能是 ASP.NET Core Cors 中的一个错误吗?我也在用钢趾。有可能它干扰了这个吗?
有什么方法可以关闭或修改预检请求吗? 感谢您提供的任何帮助!
我尝试使用各种客户端,例如httpclient、restsharp、flurl。还尝试使用 PUT 并遇到同样的问题。我也尝试过各种浏览器。预期结果是对我的 Web api 方法的成功无阻塞调用。
通过删除 Steeltoe 函数 AddAllActuators 解决了这个问题。 AddAllActuators 在 CORS 策略集合的开头添加其自己的默认 CORS 策略。这会覆盖代码中稍后设置的任何 CORS 策略。如果您需要 Steeltoe 执行器,请单独添加。示例:AddInfoActuator 添加信息执行器。这些似乎都没有自己单独的 CORS 政策。
现在您已经确定Steeltoe 参与其中,问题就变得更加清晰了。 Steeltoe 的主机构建器扩展旨在使执行器之类的东西在大多数情况下更易于使用,但它们并不总是公开较低级别可用的所有可配置性。在本例中,“应该”有一个用于自定义 CORS 策略的参数,但在某些情况下似乎忽略了该参数。 您可以使用此代码添加所有执行器并自定义 CORS 策略(如果使用多个执行器,则可以更好地控制首先定义哪个策略):
var host = WebHost.CreateDefaultBuilder()
// .AddAllActuators()
.ConfigureServices(serviceCollection =>
{
static void myPolicy(CorsPolicyBuilder policy) => policy.WithMethods("patch");
serviceCollection.AddAllActuators(buildCorsPolicy: myPolicy);
serviceCollection.ActivateActuatorEndpoints();
})