C# 无法解析操作的路由

C# 无法解析操作的路由,c#,asp.net-web-api2,asp.net-web-api-routing,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"

我正在创建一个带有如下控制器的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);
    }
}
[RoutePrefix("api/Products")]
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}
    };

    //GET api/products
    [HttpGet]
    [Route("")]
    public IEnumerable<Product> GetAllProducts()
    {
        return this.m_products;
    }

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

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

所以事实上,我试图在我的
ProductController
上有两个动作。然而,我似乎无法让第二个工作。因此,当我运行
myServer/api/products/ById/1
时,我从列表中获得第一个元素。然而,当我尝试
myServer/api/products/ByName/Hammer
时,我发现一个Http错误没有找到(404)。我还尝试了小写URL,得到了相同的结果。

您的RouteConfig定义如下:

config.Routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
但是您的
ByName
操作采用的是
name
参数,而不是
id

您需要创建一个采用
名称
参数的路由

通过装饰您的动作,您可以轻松做到这一点:

[Route("ByName/{name}")]
public IHttpActionResult GetProductByName(string name)
我忘了您还需要在控制器上包含该属性

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

您可以使用动作方法的
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);
}

有关更多详细信息,请参阅。

其中一个选项是使用
Route
属性指定资源的路由。对于您的情况,它将如下所示:

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);
    }
}
[RoutePrefix("api/Products")]
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}
    };

    //GET api/products
    [HttpGet]
    [Route("")]
    public IEnumerable<Product> GetAllProducts()
    {
        return this.m_products;
    }

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

    //GET api/products/ByName/Hammer
    [HttpGet]
    [Route("ByName/{name}")]
    public IHttpActionResult GetProductByName(string name)
    {
        var product = this.m_products.FirstOrDefault(x => x.Name == name);
        return product == null ? (IHttpActionResult) NotFound() : Ok(product);
    }
}
[RoutePrefix(“api/产品”)]
公共类产品控制器:ApiController
{
专用只读产品[]m_产品={
新产品{Id=1,Name=“番茄汤”,Category=“杂货”,Price=1},
新产品{Id=2,Name=“Yo”,Category=“Toys”,Price=375万},
新产品{Id=3,Name=“Hammer”,Category=“Hardware”,Price=16.99M}
};
//获取api/产品
[HttpGet]
[路线(“”)
公共IEnumerable GetAllProducts()
{
退回本公司产品;
}
//获取api/products/ById/1
[HttpGet]
[路由(“ById/{id:int}”)]
公共IHttpActionResult GetProductById(int id)
{
var product=this.m_products.FirstOrDefault(x=>x.Id==Id);
返回产品==null?(IHttpActionResult)NotFound():确定(产品);
}
//获取api/products/ByName/Hammer
[HttpGet]
[路由(“ByName/{name}”)]
公共IHttpActionResult GetProductByName(字符串名称)
{
var product=this.m_products.FirstOrDefault(x=>x.Name==Name);
返回产品==null?(IHttpActionResult)NotFound():确定(产品);
}
}

因为您的参数名为
name
而不是
id
。您的路由不是RESTful的。可能会考虑更改为:“产品/ {ID:INT}”“产品/ {No}}”引用和引用我认为,<代码> {ID} /COD>只是任何值的占位符。我不知道它也必须在args列表中被命名为
id
。@HimBromBeere是的,这在不久前也让我大吃一惊。检查您操作的属性我仍然会得到“没有找到与请求URI匹配的HTTP资源”。@HimBromBeere使用属性路由时,他可能缺少控制器上的
RoutePrefix(“api/products”)
route prefix属性,或者在控制器上包含整个预期路由action@Nkosi是对的,,你需要在整个url前面加上前缀generated@HimBromBeere你们应该阅读我链接的官方文档,有多种方法可以处理这个问题,所以阅读文档应该会有帮助。路由应该包含整个路由,包括π`-部分和控制器。@HimBromBeere保留您所拥有的。他们将协同工作