Web api 不同的命名操作导致多个操作错误
Web api different named actions cause Multiple actions error
我有 web api 2 个控制器操作:
[HttpGet]
public Response<IEnumerable<Product>> Get()
{
....(Get all products)
}
[HttpGet]
public Response<Product> Get(int id)
{
....(Get product by id)
}
[HttpGet]
public Response<IEnumerable<Product>> Category(int id)
{
.... (Get products by category)
}
我想将此控制器与 url 一起使用:
http://localhost/api/product
http://localhost/api/product/1
http://localhost/api/product/category/1
但是这个urlhttp://localhost/api/product/1
returns错误,
Multiple actions were found that match the request
我的配置设置是这样的:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
您的两个 Get
方法匹配相同的路由。我会删除第一个 Get
方法并更改你的第二个 Get
方法以使用可选的 id 参数,如下所示:
[HttpGet]
public Response<IEnumerable<Product>> Get(int? id)
{
// Get all products if id is null, else get product by id and return as a list with one element
}
这样,Get
将匹配 "product" 和 "product/1" 的路由。
这是在 Visual Studio 中创建新的 ASP.NET Web APi 时创建的默认控制器:
[Authorize]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
和 WebApi 配置:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
在这里使用属性路由而不是全局路由可能会更好。如果您删除全局路由并在 per-action 基础上定义路由,您应该没有问题。例如,您的路线可能如下所示:
[Route("api/product")]
[Route("api/product/{id:int}")]
[Route("api/product/category/{id:int}")]
我有 web api 2 个控制器操作:
[HttpGet]
public Response<IEnumerable<Product>> Get()
{
....(Get all products)
}
[HttpGet]
public Response<Product> Get(int id)
{
....(Get product by id)
}
[HttpGet]
public Response<IEnumerable<Product>> Category(int id)
{
.... (Get products by category)
}
我想将此控制器与 url 一起使用:
http://localhost/api/product
http://localhost/api/product/1
http://localhost/api/product/category/1
但是这个urlhttp://localhost/api/product/1
returns错误,
Multiple actions were found that match the request
我的配置设置是这样的:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
您的两个 Get
方法匹配相同的路由。我会删除第一个 Get
方法并更改你的第二个 Get
方法以使用可选的 id 参数,如下所示:
[HttpGet]
public Response<IEnumerable<Product>> Get(int? id)
{
// Get all products if id is null, else get product by id and return as a list with one element
}
这样,Get
将匹配 "product" 和 "product/1" 的路由。
这是在 Visual Studio 中创建新的 ASP.NET Web APi 时创建的默认控制器:
[Authorize]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
和 WebApi 配置:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
在这里使用属性路由而不是全局路由可能会更好。如果您删除全局路由并在 per-action 基础上定义路由,您应该没有问题。例如,您的路线可能如下所示:
[Route("api/product")]
[Route("api/product/{id:int}")]
[Route("api/product/category/{id:int}")]