Атрибуты маршрутизации Web API 2 не работают

Я использую финальную версию.NET 4.5 и Web API 2 (в Visual Studio 2013). Я использовал эту документацию как справку, но безрезультатно.

У меня есть несколько базовых маршрутов, таких как

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 / location / 12345 (получить местоположение 12345)
  • / api / местоположения / клинические (получить местоположения с "клиническими" в названии)
  • / api / location /autocomplete? ключевое слово = клинический(получить сокращенный объект Id + Name для местоположений с "клиническим" в имени)
  • / api / location /search?zipcode=12345&radius=20&name= клинический(получить местоположение в пределах 20 миль от zip 12345 с "клиническим" в названии)

В фрагменте кода ниже Get методы и Search работать по желанию, но Autocomplete не. Следует отметить, что у меня есть методы с одинаковыми именами в нескольких контроллерах. Что я делаю неправильно? (Кроме того, что именно 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);
    }

Похоже, что пока еще нет большой поддержки со стороны сообщества в отношении последних версий этого материала.

РЕДАКТИРОВАТЬ (с ответом)

Просто заменил

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

с

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

и это работает отлично.

1 ответ

Решение

Вы пытаетесь выполнить запрос GET для действий поиска и автозаполнения? Если да, то вам нужно украсить System.Web.Http.HttpGet приписывать. Если действие не имеет префикса глаголов, таких как Get, Put, Post, Delete и т. Д., Веб-API по умолчанию считается POST. Я предполагаю, что вы получаете метод 405 Not Allowed.. верно?

Свойство Name полезно в случае генерации ссылки (Url.Link) где вам нужно будет указать имя

Другие вопросы по тегам