c# - Web API 2 路由属性不起作用

标签 c# asp.net asp.net-mvc-4 asp.net-web-api asp.net-web-api-routing

我使用的是 .NET 4.5 和 Web API 2(在 Visual Studio 2013 中)的最终发行版。我一直在使用 this documentation作为引用,无济于事。

我有一些基本路线,例如

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/locations/clinical(获取名称中带有“clinical”的位置)
  • /api/locations/autocomplete?keyword=clinical (为名称中带有“clinical”的位置获取一个压缩的 Id + Name 对象)
  • /api/locations/search?zipcode=12345&radius=20&name=clinical (获取 zip 12345 20 英里范围内名称中带有“clinical”的位置)

在下面的代码块中,Get 方法和Search 可以正常工作,但Autocomplete 不能。应该注意的是,我在多个 Controller 中有类似命名的方法。我究竟做错了什么? (此外,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()]

而且效果很好。

最佳答案

您是否正在尝试对搜索和自动完成操作执行 GET 请求?如果是,那么您需要使用 System.Web.Http.HttpGet 属性进行装饰。如果一个操作没有像 Get、Put、Post、Delete 等动词前缀,Web API 默认假定为 POST。我猜您收到了 405 方法不允许..对吧?

Name 属性在需要指定名称的链接生成 (Url.Link) 的情况下很有用

关于c# - Web API 2 路由属性不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19711908/

相关文章:

c# - xUnit - 在测试中提取和实现接口(interface)

c# - DraggableView C# Xamarin 的恢复位置命令

asp.net - CSS 在 ASP.NET 中不起作用

asp.net - 部署时抛出 SecurityException

asp.net-mvc-4 - 如何使用 MVC 4 显示数据库中的二进制图像以编辑表单

c# - 什么时候适合使用错误代码?

c# - 如何有条件地调用具有约束的泛型方法?

jquery - 使用 ASP.NET MVC4 禁用取决于变量 Razor 的 div

c# - 在模型中声明列表

asp.net-mvc - MVC5中使用WEB API和Area的URL路由