无法解决路由以进行操作

时间:2018-02-23 15:14:59

标签: c# asp.net-web-api2 asp.net-web-api-routing

我正在使用这样的控制器创建一个Web-API:

public class ProductsController : ApiController
{
    private readonly Product[] m_products = {
        new Product {Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1},
        new Product {Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M},
        new Product {Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M}
    };

    public IEnumerable<Product> GetAllProducts()
    {
        return this.m_products;
    }


    [HttpGet]
    [ActionName("ById")]
    public IHttpActionResult GetProductById(int id)
    {
        var product = this.m_products.FirstOrDefault(x => x.Id == id);
        return product == null ? (IHttpActionResult) NotFound() : Ok(product);
    }

    [HttpGet]
    [ActionName("ByName")]
    public IHttpActionResult GetProductByName(string name)
    {
        var product = this.m_products.FirstOrDefault(x => x.Name == name);
        return product == null ? (IHttpActionResult) NotFound() : Ok(product);
    }
}

在我的WebApiConfig中我有这个:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "ActionApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

所以实际上我试图对ProductController进行两次操作。但是我似乎无法让第二个工作。当我运行myServer/api/products/ById/1时,我得到了我列表中的第一个元素。但是,当我尝试myServer/api/products/ByName/Hammer时,我发现未找到Http错误(404)。我还尝试使用小写的URL,结果相同。

2 个答案:

答案 0 :(得分:3)

您的RouteConfig定义如下:

config.Routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

但您的ByName操作需要name参数,而不是id

您需要创建一个带有name参数的路线。

您可以通过装饰行动轻松完成此操作:

[Route("ByName/{name}")]
public IHttpActionResult GetProductByName(string name)

我忘记了您还需要在控制器中包含RoutePrefix属性。

[RoutePrefix("api/products")]
public class ProductsController : ApiController
{

答案 1 :(得分:2)

您可以使用Route()属性为您的操作方法明确指定模式,例如:

[HttpGet]
[ActionName("ByName")]
[Route("api/Products/ByName/{name}")]
public IHttpActionResult GetProductByName(string name)
{
    var product = this.m_products.FirstOrDefault(x => x.Name == name);
    return product == null ? (IHttpActionResult) NotFound() : Ok(product);
}

有关详细信息,请参阅official documentation