C# 无法解析操作的路由
我正在创建一个带有如下控制器的Web API: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"
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保留您所拥有的。他们将协同工作