.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
相关产品推荐
相关产品推荐

