Web API路由404:在匹配的控制器上找不到任何操作

Web API Route 404: "No action was found on the controller that matches"

本文关键字:控制器 找不到 操作 任何 路由 API Web      更新时间:2023-09-26

我一直得到404,不知道为什么?

全球。ASAX:

protected void Application_Start(object sender, EventArgs e)
{
    // GetApi - Allows for:
    // - GET: With or without an Id (because id is marked as 'optional' in defaults)
    RouteTable.Routes.MapHttpRoute(name: "GetApi",
                               routeTemplate: "api/{controller}/{id}",
                               defaults: new { id = RouteParameter.Optional });
    // ActionsApi - Allows for:
    // - CREATE
    // - DELETE
    // - SAVE
    // - UPDATE
    // - LIST
    // - FIND
    // - and many, many more
    RouteTable.Routes.MapHttpRoute(name: "ActionsApi",
                       routeTemplate: "api/{controller}/actions/{action}",
                       defaults: new { });
    // QueryByNameApi - Allows for:
    // - FIND: By-Name (within the URL...not the data)
    RouteTable.Routes.MapHttpRoute(name: "QueryByNameApi",
                                   routeTemplate: "api/{controller}/actions/by-name/{value}",
                                   defaults: new
                                   {
                                       value = "",
                                       action = "QueryByName"
                                   });
}

控制器:

public class SearchController : ApiController
{
    internal const string MSG_UNMANAGEDEXCEPTION = "An unexpected error occurred. Please try again.";
    // THIS WORKS !!!
    [HttpGet]
    public HttpResponseMessage Hello()
    {
        return Request.CreateResponse(HttpStatusCode.OK, "Hello back!");
    }
    // BUT...THIS FAILS ???
    [HttpPost]
    public HttpResponseMessage Find(string value)
    {
        var result = new SearchResult();
        try
        {
            var term = value.ToLowerInvariant().Trim();
            var query = Mock.Categories();
            // WHERE
            query = query.Where(x => x.Name.ToLowerInvariant().Trim().Contains(term)
                                  || x.categoryType.Name.ToLowerInvariant().Trim().Contains(term));
            // ORDER BY
            query = query.OrderBy(x => x.Name)
                         .ThenBy(x => x.categoryType.Name);
            // MATERIALIZED
            var collection = query.ToList();
            result.Filters = collection.Select(x => x.categoryType).ToList();
            result.Records = collection;
        }
        catch (Exception ex)
        {
            HttpError error = new HttpError(MSG_UNMANAGEDEXCEPTION);
            return Request.CreateResponse(HttpStatusCode.InternalServerError, error);
        }
        return Request.CreateResponse(HttpStatusCode.OK, result);
    }
}
JAVASCRIPT:


POST失败…

$.ajax({
    type: 'POST',
    data: { "value": text },
    url: 'api/search/actions/find',
    contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
})

GET成功了吗?…

$.ajax({
    type: 'GET',
    data: {},
    url: 'api/search/actions/hello',
    contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
});

尝试将QueryByNameApirouteTemplate中的by-name替换为{action},并在SearchController中将[Route("api/search/actions/find/{value:string}")]属性添加到Find()方法中

编辑:

如果你想匹配ActionsApi,试着执行这个ajax调用:

$.ajax({
    type: 'POST',
    data: { value: text },
    url: 'api/search/actions/find',
    contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
})

else如果你想匹配QueryByNameApi试试:

$.ajax({
    type: 'POST',
    url: 'api/search/actions/find/' + value,
    contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
})

您似乎在您的帖子中发送json数据,但是您已将内容类型设置为application/x-www-form-urlencoded。我将定义一个新的类来保存你的post值,并重新定义你的post动作。

public class PostData
{
    public string value { get; set; }
}
控制器动作:

[HttpPost]
public HttpResponseMessage Find(PostData Data)
{
    string term = Data.value;
    //... implementation excluded
}

然后更改ajax调用。

$.ajax({
    type: 'POST',
    data: { "value": text },
    url: 'api/search/actions/find',
    contentType: 'application/json'
})