ASP.NET Core API部署AWS后客户端PATCH请求返回405错误
ASP.NET Core Web API PATCH请求405 Method Not Allowed错误排查
问题背景
部署在AWS Fargate的Amazon ECS上的ASP.NET Core Web API,通过Postman测试PATCH请求可正常运行,但客户端实现相同请求后返回StatusCode: 405, ReasonPhrase: 'Method Not Allowed',响应头显示允许的方法仅为GET、PUT。
客户端代码
public async Task<ActionResult> Patch(int companyId, string description) { JsonPatchDocument<CompanyInfo> patchDoc = new JsonPatchDocument<CompanyInfo>(); patchDoc.Replace(e => e.Description, description); var jsonSerializeObject = JsonConvert.SerializeObject(patchDoc); Debug.WriteLine(jsonSerializeObject); var method = new HttpMethod("PATCH"); var request = new HttpRequestMessage(method, "api/CompanyInfo/" + companyId) { Content = new StringContent(jsonSerializeObject, Encoding.Unicode, "application/json") }; response = await _httpClient.SendAsync(request); Debug.WriteLine(response); return RedirectToAction(nameof(Index)); }
响应信息
StatusCode: 405, ReasonPhrase: 'Method Not Allowed', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers: { Date: Sat, 26 Nov 2022 06:06:08 GMT Connection: keep-alive Server: Kestrel Content-Length: 0 Allow: GET, PUT }
Postman验证可用的JSON Patch文档
[ { "value":"some text value", "path":"/Description", "op":"replace" } ]
API代码
[HttpPatch] public async Task<ActionResult> PartiallyUpdateCompanyInfo(int companyId, JsonPatchDocument<CompanyInfoForPatchDto> patchDocument) { var companyEntity = await _moviePlanetRepository.GetCompanyById(companyId, false); if (companyEntity == null) { return NotFound(); } var companyToPatch = _mapper.Map<CompanyInfoForPatchDto>(companyEntity); patchDocument.ApplyTo(companyToPatch, ModelState); if (!ModelState.IsValid) { return BadRequest(ModelState); } if (!TryValidateModel(companyToPatch)) { return BadRequest(ModelState); } _mapper.Map(companyToPatch, companyEntity); await _moviePlanetRepository.Save(); return NoContent(); }
原因分析
- 路由未明确匹配:API的
[HttpPatch]未指定具体路由模板,若控制器路由前缀为api/CompanyInfo,方法需显式绑定{companyId}参数才能匹配客户端请求的api/CompanyInfo/{companyId}路径。 - DTO类型不匹配:客户端使用
JsonPatchDocument<CompanyInfo>生成请求内容,而API接收的是JsonPatchDocument<CompanyInfoForPatchDto>,序列化后的字段结构可能存在差异,导致请求无法命中目标方法。 - 请求编码不一致:客户端使用
Encoding.Unicode(UTF-16)发送请求,Postman默认使用UTF-8,部分服务器配置对编码敏感,可能导致请求解析失败,触发405错误。
解决方法
1. 修正API路由配置
确保控制器有正确的路由前缀,且HttpPatch方法明确指定路由参数:
[Route("api/[controller]")] [ApiController] public class CompanyInfoController : ControllerBase { [HttpPatch("{companyId}")] // 绑定companyId参数到路由 public async Task<ActionResult> PartiallyUpdateCompanyInfo(int companyId, JsonPatchDocument<CompanyInfoForPatchDto> patchDocument) { // 原有业务逻辑 } }
2. 统一DTO类型
客户端使用与API一致的CompanyInfoForPatchDto创建JsonPatchDocument,避免类型差异:
// 客户端代码修改 JsonPatchDocument<CompanyInfoForPatchDto> patchDoc = new JsonPatchDocument<CompanyInfoForPatchDto>(); patchDoc.Replace(e => e.Description, description);
3. 调整请求编码为UTF-8
将客户端请求编码改为UTF-8,与Postman保持一致:
Content = new StringContent(jsonSerializeObject, Encoding.UTF8, "application/json")
4. 验证请求URL正确性
确认客户端请求URL与Postman完全一致,检查是否存在拼写错误、前缀缺失等问题。
内容的提问来源于stack exchange,提问作者khaira777
相关产品推荐
相关产品推荐

