当我试图从Blazor Wasm调用AspNetCore Restful API时,收到一个"TypeError:Failed to fetch"错误。我可以称之为邮差,它运行良好。
我的环境:Microsoft Visual Studio社区2019预览版16.6.0预览版3.0
客户端:Blazor Wasm服务(dotnetstandard 2.1(
- AspNet.WebApi.Client 5.2.7
- AspNetCore。。WebAssembly 3.2预览4.2
- System.Net.Http.Json 3.2预览5.2
重要用途:
using Microsoft.AspNetCore.JsonPatch;
using Newtonsoft.Json;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
省略了父命名空间和类_httpClient被注入父类
public async Task<MyDto> UpdatePartialAsync(Guid primaryId, ObjectForUpdateDto objectForUpdateDto)
{
MyDto dtoFromApi = null;
var patchDoc = new JsonPatchDocument<ObjectForUpdateDto>()
.Replace(o => o.Name, objectForUpdateDto.Name)
.Replace(o => o.Description, objectForUpdateDto.Description)
var uri = $"MyUri/myResources/{primaryId}";
try
{
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var serializedPatchDoc = JsonConvert.SerializeObject(patchDoc);
var json = new StringContent(serializedPatchDoc, Encoding.UTF8, "application/json-patch+json");
var response = await _httpClient.PatchAsync(uri, json);
return await response.Content.ReadAsAsync<MyDto>();
}
catch (Exception)
{
throw; //throws 'TypeError: Failed to fetch'
}
return dtoFromApi;
}
我的API(.Net 5.0,也尝试过.Net Core 3.1(:
[HttpPatch]
[Route("{primaryId}")]
public ActionResult UpsertPartial([FromRoute]Guid primaryId, [FromBody] JsonPatchDocument<ObjectForUpdateDto> objectForUpdateDto)
{
//client call never makes it here
return NoContent();
}
多么误导性的错误消息。这是一个CORS问题。
修复是在API的startup.csConfigureServices
方法(以前是"GET, DELETE, PUT, POST, OPTIONS"
(中将"PATCH"
添加到我的CORS策略中。
services.AddCors(options =>
{
options.AddPolicy(CorsAllowAll,
builder =>
{
builder.WithOrigins(Constants.ApiClientCors).AllowAnyHeader().WithMethods("GET, PATCH, DELETE, PUT, POST, OPTIONS");
});
});
@inliner49er,我希望我能添加一条评论来澄清你的回答,因为你的回答是正确的,但我没有足够的信誉点。因此,我将把我对你的答案的调整作为一个单独的答案发布。
你搞定了,CORS问题也修复了我的程序。代码中唯一没有意义的部分是对一个名为Constants
的类的引用。我正在尝试完成PluralSight教程,因为我完全在内部工作,我可以安全地用以下代码替换您的代码:
services.AddCors(options =>
{
options.AddPolicy("PolicyName", builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
我对这一切都非常陌生,在学习的过程中已经花了几个小时了,所以我有一点不理解。我只是想发这个帖子来帮助那些可能有类似问题的人。
您也可以尝试将这些行直接添加到Startup
类的Configure
方法中:
//ENABLE CORS
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowed(origin => true) // allow any origin
.AllowCredentials()); // allow credentials