You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 22:05:22