【问题标题】:WebApi not finding action on controllerWebApi 未在控制器上找到操作
【发布时间】: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 时,您需要非常关注浏览器如何处理跨站点源策略。希望这会有所帮助

标签: c# ajax asp.net-web-api


【解决方案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 个参数的构造函数
猜你喜欢
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多