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();

然后使用 RoutePrefixRoute 属性装饰您的 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“找到多个类型匹配名为...的控制器”

调用具有 2 个参数的 WebAPI 控制器操作

csharp 标准脚手架EntityFramework与异步操作WebAPI控制器

WebAPI 错误 404.0 - 未找到

如何让登录用户退出.Net WebAPI中的控制器操作方法

MVC WebApi 路由未找到 HTTP 资源