[英]asp.net WebAPI Two controllers with same routes but different verbs
[英]ASP.NET WebApi - Two Controllers With Similar Action Methods
我有一个场景,其中有2个不同的控制器,每个控制器都有多个Get方法。 我ActionName
属性修饰的方法,但是路由没有按我认为的那样工作。
ContactController
public ContactModel GetContactByID(string id)
{
...
}
[ActionName("username")]
public ContactModel GetContactByUserName(string text)
{
...
}
PaymentController
public PaymentModel Get(Guid id)
{
...
}
[HttpGet, ActionName("sale")]
public PaymentActivityModel Sale(Guid id)
{
...
}
路线
config.Routes.MapHttpRoute(
"PaymentControllerActionId",
"api/client/{clientId}/{controller}/{action}/{id}",
defaults: null
);
config.Routes.MapHttpRoute(
"ContactControllerActionText",
"api/client/{clientId}/{controller}/{action}/{text}",
defaults: null
);
config.Routes.MapHttpRoute(
"ClientControllerId",
"api/client/{clientId}/{controller}/{id}",
new { id = RouteParameter.Optional }
);
当我导航到“付款”时,它可以正常工作。 但是,当我导航到“联系人”时,会收到:
找不到与请求URI匹配的HTTP资源... / api / client /.../ contact / username / exampleUserName
在控制器“联系人”上未找到与请求匹配的操作。
我的印象是参数名称将与动作名称( text
与id
)匹配。
是一个人使用Guid
ID,一个人使用string
ID的问题吗?
这是一个面向客户端的API,我有一个字符串的客户端友好型ContactID。 而PaymentID是Guid。
首先,我想指出您的路线没有多大意义。
此路由说它是用于PaymentControllerActionId的,但是您将路由保留为打开状态以使用任何控制器,而不是指定仅用于Payment Controller。
config.Routes.MapHttpRoute(
"PaymentControllerActionId",
"api/client/{clientId}/{controller}/{action}/{id}",
defaults: null
);
回答您的问题。 您可能需要指定{text}作为可选的RouteParameter。 否则,框架通常期望您已定义了自定义路由约束(并且您应该在{clientId} IMO上具有路由约束)。
另外,如果您的一项操作需要GUID。 将其作为Guid参数类型,WebAPI将正确匹配它。 或者,由于两个函数都期望使用名称或guid,因此您可能只有一个带有字符串的函数,然后在数据库中执行与GUID或NAME匹配的select语句并返回联系人。 更少的代码,更易于阅读,更有意义。
如果您使用的是Web API 2,则可以为此目的使用属性路由。
在下面的示例中,控制器混合使用常规+属性路由,但是您可以根据需要将其更改为仅通过属性路由进行。
例:
路由配置
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
"ClientControllerId",
"api/client/{clientId}/{controller}/{id}",
new { id = RouteParameter.Optional }
);
ContactController
[RoutePrefix("api/client/{clientId}/Contact")]
public class ContactController
{
// this uses conventional route
public ContactModel GetContactByID(string id)
{
...
}
[Route("username/{userName}")]
public ContactModel GetContactByUserName(string userName)
{
...
}
}
PaymentController
[RoutePrefix("api/client/{clientId}/Payment")]
public class PaymentController
{
// this uses conventional route
public PaymentModel Get(Guid id)
{
...
}
[HttpGet, Route("sale/{id}")]
public PaymentActivityModel Sale(Guid id)
{
...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.