2015-07-19 40 views
0

我不斷收到404,看不到原因?Web API Route 404:「在控制器上找不到匹配的動作」

的Global.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' 
}); 

回答

0

嘗試在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' 
}) 

否則,如果你想匹配QueryByNameApi嘗試:

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

不應該「ActionsApi」優先於「QueryByNameApi」嗎? –

+0

另外,爲什麼我必須使用[Route]屬性「進一步定義」控制器中的路由?這不是「RouteTable」的工作嗎? –

+0

執行你的第二個Ajax調用應該優先。但我認爲你應該在第一個ajax調用中輸入'url'像'url:'api/search/actions/find /'+ value'。 –

0

你出現在你的崗位上被髮送JSON數據,但是你有你的內容類型設置爲application/x-www-form-urlencoded。 我會定義一個新類來保存您的發佈值並重新定義您的發佈操作。

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' 
}) 
相關問題