无法解析操作路由
cannot resolve routing for action
我正在用这样的控制器创建 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
上执行两个操作。但是我似乎无法让第二个工作。 Thuis 当我 运行 myServer/api/products/ById/1
我从我的列表中得到第一个元素。但是,当我尝试 myServer/api/products/ByName/Hammer
时,我得到一个 Http-error not found (404)。我还尝试了小写的 URL,结果相同。
您的 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
{
您可以使用 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
属性来指定资源的路由。对于您的情况,它看起来像这样:
[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);
}
}
我正在用这样的控制器创建 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
上执行两个操作。但是我似乎无法让第二个工作。 Thuis 当我 运行 myServer/api/products/ById/1
我从我的列表中得到第一个元素。但是,当我尝试 myServer/api/products/ByName/Hammer
时,我得到一个 Http-error not found (404)。我还尝试了小写的 URL,结果相同。
您的 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
{
您可以使用 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
属性来指定资源的路由。对于您的情况,它看起来像这样:
[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);
}
}