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

.NET MAUI 7调用API遇405错误:Get正常,Post/Put/Delete失败

问题:.NET MAUI 7中POST/PUT/DELETE请求返回405 Method Not Allowed,GET请求正常

核心场景

同一套Web API控制器,Web客户端调用所有方法都正常,但在Android 10(API 29)设备上的.NET MAUI 7项目中,GET/GET By ID请求正常,POST/PUT/DELETE请求返回405错误,怀疑API Key Header存在问题。

关键代码参考

后端Web API控制器(无授权)

//[Authorize]
[Route("api/System/GetSsC09EVideoType")]
[HttpGet]
public IHttpActionResult GETSsC09EVideoType()
{
    IList<SsC09EVideoType> entity = SsC09EVideoTypeModel.SaCLSsC09EVideoType();
    return Ok(entity);
}
[Route("api/System/GetSsC09EVideoTypeByID")]
[HttpGet]
public IHttpActionResult GETSsC09EVideoTypeByID(int SID)
{
    SsC09EVideoType entity = SsC09EVideoTypeModel.ReCLSsC09EVideoType(SID);
    return Ok(entity);
}
[Route("api/System/PostSsC09EVideoType")]
[HttpPost]
public IHttpActionResult POSTSsC09EVideoType([FromBody] SsC09EVideoType mySsC09EVideoType)       
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    int count = SsC09EVideoTypeModel.InSsC09EVideoType(mySsC09EVideoType);
    return Ok(count);
}
[Route("api/System/PutSsC09EVideoType")]
[HttpPut]
public IHttpActionResult PUTSsC09EVideoType(int SID, [FromBody] SsC09EVideoType mySsC09EVideoType)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    bool isUpdate = SsC09EVideoTypeModel.UpSsC09EVideoType(mySsC09EVideoType, SID);
    return Ok(isUpdate);
}
[Route("api/System/DeleteSsC09EVideoType")]
[HttpDelete]
public IHttpActionResult DELETESsC09EVideoType(int SID)
{
    bool isDelete = SsC09EVideoTypeModel.DeSsC09EVideoType(SID);
    return Ok(isDelete);
}

MAUI中正常运行的GET请求代码

public static async Task<SsC09EVideoType> ReCLSsC09EVideoType(string myToken, int SID)
{
    using (Global.client = new HttpClient())
    {
        Global.client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        Global.client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", myToken);
        Global.client.DefaultRequestHeaders.Add("APIKey", Global.APIKey);
        try
        {
            SsC09EVideoType myobj = null;
            HttpResponseMessage response = await Global.client.GetAsync(Global.BaseUrlAddress + "api/System/GetSsC09EVideoTypeByID?SID=" + SID);
            if (response.IsSuccessStatusCode)
            {
                myobj = response.Content.ReadFromJsonAsync<SsC09EVideoType>().Result;
                return myobj;
            }
            
            return myobj;
        }
    }
  
}

MAUI中返回405的POST请求代码(示例)

public static async Task<int> InSsC09EVideoType(string myToken, SsC09EVideoType myCl)
{
    using (Global.client = new HttpClient())
    {
        Global.client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        Global.client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", myToken);
        Global.client.DefaultRequestHeaders.Add("APIKey", Global.APIKey);
        int sid = -1;
        try
        {                    
            HttpResponseMessage response = await Global.client.PostAsJsonAsync(Global.BaseUrlAddress + "api/System/PostSsC09EVideoType", myCl);
            if (response.IsSuccessStatusCode)
            {
                sid = response.Content.ReadFromJsonAsync<int>().Result;
                return sid;
            }                   
            return sid;
        }               
    }           
}

排查与解决方案

1. 优先确认API Key的一致性与正确性

  • 对比GET和POST请求的API Key传递:GET用的是Global.APIKey,但测试HttpRequestMessage时硬编码了"123",确保所有请求使用同一个有效API Key,避免测试时的硬编码错误。
  • 检查Header名称的大小写:后端是否对Header名称大小写敏感?比如后端期望ApiKey而你传的是APIKey,虽然HTTP头理论上不区分大小写,但部分服务器配置会严格校验,统一成和后端一致的写法。
  • 临时禁用API Key校验:后端注释掉API Key相关校验逻辑,MAUI也去掉添加API Key的代码,测试POST请求是否正常。如果正常,说明问题出在API Key的传递或校验环节。

2. 检查CORS跨域配置(最可能的原因)

Web端正常但MAUI报错,大概率是CORS策略未放行非GET方法或自定义Header:

  • 若后端是ASP.NET Core,确保CORS配置包含所有需要的方法和Header:
    app.UseCors(builder => builder
        .AllowAnyOrigin() // 移动端建议用这个,或指定具体源
        .AllowAnyHeader() // 放行自定义Header如APIKey
        .AllowAnyMethod()); // 包含POST/PUT/DELETE
    
  • 若后端是旧版Web API,在WebApiConfig.cs中配置:
    config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
    
  • 注意:405错误常伴随CORS预检(OPTIONS请求)失败,MAUI发送非简单请求时会先发起OPTIONS请求,若后端未处理或CORS未放行OPTIONS,就会返回405。

3. 校验后端路由与请求参数匹配

  • 确认POST/PUT/DELETE的路由拼写完全一致:比如MAUI请求的api/System/PostSsC09EVideoType和后端[Route]属性是否完全匹配,无多余斜杠或大小写差异。
  • 检查PUT方法的参数:后端PUT需要int SID作为URL参数,MAUI的PUT请求必须在URL中携带SID(比如api/System/PutSsC09EVideoType?SID=123),或修改后端路由为[Route("api/System/PutSsC09EVideoType/{SID}")],MAUI请求api/System/PutSsC09EVideoType/123。参数缺失会导致后端找不到对应Action,返回405。

4. 抓包对比请求细节

用Charles或Fiddler抓取MAUI的POST请求,和Web端的正常POST请求对比:

  • 确认请求方法确实是POST,未被重定向或修改
  • 对比请求头:APIKey、Authorization、Content-Type是否完全一致
  • 检查请求体:JSON结构、字段大小写是否和Web端一致,无缺失字段

5. 优化MAUI的HttpClient配置

  • 避免每次请求新建HttpClient,全局复用一个实例(比如在App.xaml.cs中初始化一次),减少连接池问题。
  • 确保Content-Type正确:PostAsJsonAsync会自动设置application/json,手动创建StringContent时确认第三个参数为"application/json"。

内容的提问来源于stack exchange,提问作者Chan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 20:39:55