.NET Core API的HttpPatchAsync接口在Windows正常运行但Linux容器中抛出JsonReaderException异常的问题
首先,这个错误Unexpected character encountered while parsing value: M很关键——它说明你的Blazor应用尝试解析的响应内容不是预期的布尔值JSON(true/false),而是以字母M开头的字符串(比如常见的Method Not Allowed错误提示)。结合Windows本地正常、容器部署异常的情况,我们可以一步步排查:
第一步:先搞清楚API实际返回了什么
在Blazor的UpdateEntity方法里临时添加日志,打印出API的响应内容和状态码,这是定位问题的核心:
public async Task<bool> UpdateEntity(TestObject entity) { var content = new StringContent(JsonConvert.SerializeObject(entity), Encoding.UTF8, "application/json"); using (var httpClient = new HttpClient()) { using (var response = await httpClient.PatchAsync(@"http://someserverpath:5000/api/v1/Customer", content)) { string apiResponse = await response.Content.ReadAsStringAsync(); // 打印响应内容和状态码,方便排查 Console.WriteLine($"API Response: {apiResponse}"); Console.WriteLine($"Status Code: {response.StatusCode}"); if (!response.IsSuccessStatusCode) { // 提前抛出异常,避免后续解析错误 throw new HttpRequestException($"Request failed: {response.StatusCode} - {apiResponse}"); } return JsonConvert.DeserializeObject<bool>(apiResponse); } } }
运行后查看日志,大概率会看到类似Method Not Allowed(状态码405)或者其他错误信息,接下来对应处理:
常见问题及解决方案
1. 遇到405 Method Not Allowed(最可能的情况)
这说明你的API所在的Linux环境(比如反向代理nginx、或者.NET Core的CORS配置)没有允许PATCH方法:
解决方法:
- 检查CORS配置:在API的
Program.cs(或Startup.cs)里,确保CORS策略允许PATCH方法:builder.Services.AddCors(options => { options.AddPolicy("AllowBlazorApp", policy => { policy.WithOrigins("你的Blazor应用域名") // 建议明确指定,不要用AllowAnyOrigin .AllowAnyHeader() .AllowAnyMethod(); // 或者明确列出:.WithMethods("GET", "POST", "PUT", "PATCH", "DELETE") }); }); // 注意:这个中间件要放在UseRouting之后,UseAuthorization之前 app.UseCors("AllowBlazorApp"); - 检查反向代理配置:如果用了nginx作为容器的反向代理,需要在location块里允许PATCH方法,并正确处理OPTIONS预检请求:
location / { add_header Access-Control-Allow-Origin "你的Blazor应用域名"; add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type"; # 处理OPTIONS预检请求 if ($request_method = OPTIONS) { return 204; } # 其他代理配置... proxy_pass http://localhost:5000; }
2. 遇到400 Bad Request
这说明API的模型绑定失败了,虽然你用了JsonProperty指定字段名,但可以在API的控制器方法里添加模型验证检查:
public async Task<IActionResult> PatchAsync([FromBody] TestObject entity) { if (!ModelState.IsValid) { // 返回验证错误,方便前端排查 return BadRequest(ModelState); } return Ok(await _service.PatchAsync(entity)); }
同时查看API容器的日志(运行docker logs <你的API容器ID>),看具体的验证失败原因。
3. 遇到500 Internal Server Error
这说明API的服务层(_service.PatchAsync(entity))抛出了异常,直接查看API容器的日志,定位具体的异常信息,比如数据库连接问题、业务逻辑错误等。
4. JSON序列化版本差异
确保你的Blazor应用和.NET Core API使用的Newtonsoft.Json版本完全一致,版本不匹配可能导致序列化/反序列化的差异。同时可以在API里明确配置Newtonsoft.Json的序列化规则,和前端保持一致:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new DefaultContractResolver(); options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; // 其他和前端一致的配置... });
最后验证容器内的网络连通性
如果上述配置都没问题,可以进入Blazor容器,用curl测试API端点:
docker exec -it <你的Blazor容器ID> bash # 发送PATCH请求测试 curl -X PATCH http://someserverpath:5000/api/v1/Customer -d '{"Code":"test","Name":"test"}' -H "Content-Type: application/json"
看返回的内容和状态码,进一步确认问题。
内容的提问来源于stack exchange,提问作者BankMan101

