WebApi 未在控制器上找到操作
Posted
技术标签:
【中文标题】WebApi 未在控制器上找到操作【英文标题】:WebApi not finding action on controller 【发布时间】:2019-02-16 06:59:24 【问题描述】:下午好。 但是,我创建了一个试图访问我的 C# 函数的 ajax 调用;我收到错误“在与请求匹配的控制器‘PortalApi’上未找到任何操作。”请求是一个帖子,并且服务器函数附加了相应的 Http 标头。函数名称和参数也都相同。
阿贾克斯
GetExtendersGridDataFromServer(requestParameters)
extendersGridSource = null;
var gridFilterParams = JSON.stringify(requestParameters);
$.ajax(
async: false,
contentType: "application/json",
converters: Utills.jQueryAjaxJsondDataConverter,
data: JSON.stringify( gridFilterParams: gridFilterParams, securityCode: securityCode ),
dataType: "jsond",
type: "POST",
url: (Utills.getBaseURL() + "/Api/PortalApi/GetExtenderGridData"),
error: function (XMLHttpRequest, textStatus, errorThrown)
alert(XMLHttpRequest.responseText);
,
failure: function (msg)
alert("failure");
,
success: function (msg)
alert("success");
);
C#
[HttpPost]
public JqGridData GetExtenderGridData(string securityCode)
IMUserSecurity.UserSecurity.ValidateWebMethodSecurityCode(securityCode, "PortalWebService.GetExtenderGridData");
return GetDoctorGridData("extender");
路由配置
configuration.Routes.MapHttpRoute("API Action Default", "api/controller/action/id",
new
id = RouteParameter.Optional
);
【问题讨论】:
控制器类的名称是什么? 在路由配置中,添加一个'?'在id
之后。比如"configuration.Routes.MapHttpRoute("API Action Default", "api/controller/action/id?","
。否则 url 中需要一个 id 值来匹配这个路由配置
@Clint PortalApiController
检查您的浏览器调试选项卡。现代浏览器将通过在发送 HTTP-POST 之前发送 HTTP-OPTION 请求来检查跨站点源策略。根据您的代码,找不到选项端点因此失败。您可以将 [HttpOption] 标记添加到端点或一起删除 [HTTPPost] 以进行测试。在 .net 中编写 WebAPI 时,您需要非常关注浏览器如何处理跨站点源策略。希望这会有所帮助
【参考方案1】:
这里有两个可能的问题:
路由
我建议您使用属性路由而不是依赖于约定路由(IMO 可能会很痛苦)
在WebApiConfig.cs的Register
方法中启用属性路由
config.MapHttpAttributeRoutes();
然后使用 RoutePrefix
和 Route
属性装饰您的 api 控制器和 api 方法。 RoutePrefix
+ Route
结合起来构建您的方法的完整路线,在这个
例如api/PortalApi/GetExtenderGridData
[RoutePrefix("api/PortalApi")]
public class PortalApiController : ApiController
[Route("GetExtenderGridData")]
[HttpPost]
public IEnumerable<Order> FindOrdersByCustomer(int customerId) ...
请求正文
您的 api 方法 FindOrdersByCustomer
将一个字符串作为参数,但您的客户端正在尝试向该方法发送一个对象,目前这是不可能的。
客户端对象定义为
gridFilterParams: gridFilterParams, securityCode: securityCode
为了能够将其发送到后端 api,您需要确保它与该签名匹配。
创建一个反映客户端模型的类(我不知道gridFilterParams
是什么,但你明白了这里的意思)
public class RequestModel
public object GridFilterParams get;set;
public string SecurityCode get; set;
然后从 api 方法中的请求正文中读取它
[RoutePrefix("api/PortalApi")]
public class PortalApiController : ApiController
[Route("GetExtenderGridData")]
[HttpPost]
public IEnumerable<Order> FindOrdersByCustomer([FromBody]RequestModel model) ...
【讨论】:
你的回答也不错,他刚来。感谢您提供的所有知识。【参考方案2】:尝试添加 FromBody 属性 (more info)。
public JqGridData GetExtenderGridData([FromBody] Security security) ...
public class Security
public object GridFilterParams get; set;
public string SecurityCode get; set;
【讨论】:
然而,它命中了 GetExtenderGridData 函数;安全似乎迷路了。 我更新了我的回复。尝试将其更新为上面的代码。【参考方案3】:我没有足够的声誉来发表评论,但你可以试试这个
[HttpPost("GetExtenderGridData")
而不是
[HttpPost].
【讨论】:
HttpPostAttribute' 不包含带 1 个参数的构造函数以上是关于WebApi 未在控制器上找到操作的主要内容,如果未能解决你的问题,请参考以下文章
MVC & WebAPI“找到多个类型匹配名为...的控制器”