12

我正在使用最終版本的.NET 4.5和Web API 2(在Visual Studio 2013中)。我一直在使用this documentation作爲參考,無濟於事。Web API 2路由屬性不起作用

我有幾個基本路線像

api/providers 
api/locations 
api/specialties 

而像

Get() 
Get(int id) 
Get(string keyword) 
Autocomplete(string keyword) 
Search(string zipcode, string name, int radius, [...]) 

理想的每個一些方法,我想的URL落得像

  • /api/locations/12345(獲取位置12345)
  • /API /位置/臨牀(獲取與在名稱爲 「臨牀」 位置)
  • /API /位置/自動完成?關鍵字=臨牀 (得到稠編號+名稱對象與「臨牀地點「的名字)
  • /API /位置/搜索?郵編= 12345米&半徑= 20 &名=臨牀 (送拉鍊12345的20英里內的位置 」之名臨牀「)

在下面的代碼塊中,Get方法和Search按需要工作,但​​3210沒有。應該指出,我在多個控制器中有相似的命名方法。我究竟做錯了什麼? (另外,究竟是什麼Name =屬性?)

/// <summary> 
/// This is the API used to interact with location information. 
/// </summary> 
[RoutePrefix("api/locations")] 
public class LocationController : ApiController 
{ 
    private ProviderEntities db = new ProviderEntities(); 

    private static readonly Expression<Func<Location, LocationAutocompleteDto>> AsLocationAutocompleteDto = 
     x => new LocationAutocompleteDto 
     { 
      Id = x.Id, 
      Name = x.Name 
     }; 

    /// <summary> 
    /// Get ALL locations. 
    /// </summary> 
    [Route("")] 
    public IQueryable<Location> Get() 
    { 
     return db.Locations.AsQueryable(); 
    } 

    /// <summary> 
    /// Get a specific location. 
    /// </summary> 
    /// <param name="id">The ID of a particular location.</param> 
    [Route("{id:int}")] 
    public IQueryable<Location> Get(int id) 
    { 
     return db.Locations.Where(l => l.Id == id); 
    } 

    /// <summary> 
    /// Get all locations that contain a keyword. 
    /// </summary> 
    /// <param name="keyword">The keyword to search for in a location name.</param> 
    [Route("{keyword:alpha}")] 
    public IQueryable<Location> Get(string keyword) 
    { 
     return db.Locations.Where(l => l.Name.Contains(keyword)).OrderBy(l => l.Name); 
    } 

    [Route("search", Name = "locationsearch")] 
    public string Search(string zipcode = null, string latitude = null, string longitude = null) 
    { 
     if (zipcode != null) return "zipcode"; 
     if (latitude != null && longitude != null) return "lat/long"; 
     else 
      return "invalid search"; 
    } 

    /// <summary> 
    /// Autocomplete service for locations, returns simple Id/Name pairs. 
    /// </summary> 
    /// <param name="keyword">The keyword to search on.</param> 
    [Route("autocomplete/{keyword:alpha}", Name = "locationautocomplete")] 
    public IQueryable<LocationAutocompleteDto> Autocomplete(string keyword) 
    { 
     // validate the inputs 
     if (string.IsNullOrEmpty(keyword)) 
      return null; 

     IQueryable<Location> results = from l in db.Locations 
             where l.Name.Contains(keyword) 
             select l; 

     return results.Select(AsLocationAutocompleteDto); 
    } 

似乎有不被周圍很多這方面的東西的最新版本的社區支持呢。

EDIT(含答案)

簡單地更換

[Route("autocomplete/{keyword:alpha}", Name = "locationautocomplete")] 

[Route("autocomplete"), Route("autocomplete/{keyword:alpha}", HttpGet()] 

和它完美的作品。

回答

5

您是否試圖對搜索和自動完成操作執行GET請求?如果是,那麼你需要用System.Web.Http.HttpGet屬性來裝飾。如果一個動作沒有以Get,Put,Post,Delete等動詞作爲前綴,則默認情況下Web API假定爲POST。我猜你正在接受405方法不允許..對吧?

Name屬性的鏈接產生的情況下是有用的(Url.Link),您將需要指定一個名稱

+1

謝謝!!我改變了[[Route(「autocomplete/{keyword:alpha}」,Name =「locationautocomplete」)]''[Route(「autocomplete」),Route(「autocomplete/{keyword:alpha}」),HttpGet ()]'現在完美。 'HttpGet()'屬性是關鍵,並且將兩個Route()定義鏈接在一起使它以我期望的兩種不同方式工作。 –