I'm using the final release versions of .NET 4.5 and Web API 2 (in Visual Studio 2013). I've been using this documentation as a reference, to no avail.
I have a few base routes like
api/providers
api/locations
api/specialties
And some methods on each like
Get()
Get(int id)
Get(string keyword)
Autocomplete(string keyword)
Search(string zipcode, string name, int radius, [...])
Ideally, I'd like the URLs to end up like
In the chunk of code below, the Get methods and Search work as desired, but Autocomplete does not. It should be noted I have similarly named methods in multiple controllers. What am I doing wrong? (Also, what exactly is the Name = property for?)
/// <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);
    }
There does not seem to be a lot of community support around the latest versions of this stuff yet.
Simply replaced
[Route("autocomplete/{keyword:alpha}", Name = "locationautocomplete")]
with
[Route("autocomplete"), Route("autocomplete/{keyword:alpha}", HttpGet()]
and it works perfectly.
Are you trying to do a GET request on Search and AutoComplete actions? If yes, then you would need to decorate with a System.Web.Http.HttpGet attribute. If an action isn't prefixed by verbs like Get, Put, Post, Delete etc, Web API by defaults assumes as POST. I am guessing you are receiving a 405 Method Not Allowed..right?
The Name property is useful in case of link generation (Url.Link) where you would need to specify a name
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With