Angular2+ TypeScript应用调用WebAPI遇405 Method Not Allowed错误求助
从你给出的错误信息和代码来看,问题的核心是前后端请求方法不匹配,同时还有几处小细节需要修正,下面一步步帮你解决:
1. 核心问题:请求方法不匹配
你的前端代码用的是POST请求(this.http.post(...)),但后端接口标注的是[HttpGet],这直接导致了405错误——后端只接受GET请求,而你发了POST,自然会提示"The requested resource does not support http method 'POST'."
解决方案A:把后端改成POST请求(推荐)
因为你需要传递比较复杂的请求体(包含Filter、Skip、Take、Sort这些结构化数据),POST请求更适合这种场景。只需要把后端的[HttpGet]改成[HttpPost]即可:
[HttpPost] // 这里从HttpGet改成HttpPost public HttpResponseMessage GetUserRequestsByStatuses([FromBody] DataRequest model) { DataResponse<AngKendoGridDashboard> response = BusinessAccess.GetUserRequestsByStatuses(model); return CreateHttpResponse(response); }
2. 前端代码的小bug修正
你的前端代码里有一个headers的错误:你定义了var headers = new Headers();,但在请求里用的是{ headers: this.headers },这里应该用你刚创建的headers变量,否则会使用类里未定义的headers(导致请求头异常):
getUserRequests(statusId: number, skip: number, take: number, sort: SortDescriptor[]): Observable<GridResult> { const getUserRequestsUrl = environment.serviceHostName + environment.serviceAppURL + '/api/Dashboard/GetUserRequestsByStatuses'; const headers = new Headers(); headers.append('Content-Type', 'application/json;'); return this.http.post(getUserRequestsUrl, JSON.stringify({ "Filter": { "Field": "StatusId", "Value": statusId, "Operator": "eq" }, "Skip": skip, "Take": take, "Sort": sort }), { headers: headers }) // 这里把this.headers改成headers .share() .map((res: Response) => res.json()) .map(response => (<GridResult>{ data: response.Data , total: response.Count })); }
3. 备选方案:如果一定要用GET请求
如果业务上必须用GET,那需要把所有参数拼到URL的查询字符串里(因为GET请求通常不携带请求体,后端的[FromBody]也无法读取GET请求的body):
前端修改:
getUserRequests(statusId: number, skip: number, take: number, sort: SortDescriptor[]): Observable<GridResult> { const getUserRequestsUrl = environment.serviceHostName + environment.serviceAppURL + '/api/Dashboard/GetUserRequestsByStatuses'; // 把参数转换成查询字符串 const params = new URLSearchParams(); params.append('StatusId', statusId.toString()); params.append('Skip', skip.toString()); params.append('Take', take.toString()); // 处理Sort数组,转换成JSON字符串传递 params.append('Sort', JSON.stringify(sort)); return this.http.get(getUserRequestsUrl, { params: params }) .share() .map((res: Response) => res.json()) .map(response => (<GridResult>{ data: response.Data , total: response.Count })); }
后端修改:
去掉[FromBody],改成从URL参数接收,或者创建匹配的模型并用[FromUri](适用于旧版Web API):
[HttpGet] public HttpResponseMessage GetUserRequestsByStatuses([FromUri] DataRequest model) { DataResponse<AngKendoGridDashboard> response = BusinessAccess.GetUserRequestsByStatuses(model); return CreateHttpResponse(response); }
注意:如果用这种方式,你的DataRequest模型需要能和查询参数正确绑定,Sort数组可能需要额外处理序列化/反序列化逻辑。
最后验证
修改完成后,重新启动前后端服务,用浏览器开发者工具的Network面板查看请求的方法、URL和参数是否正确,确保请求能正常到达后端接口。
内容的提问来源于stack exchange,提问作者HereToLearn_

