繁体   English   中英

ASP.NET WebApi-具有类似操作方法的两个控制器

[英]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

在控制器“联系人”上未找到与请求匹配的操作。

我的印象是参数名称将与动作名称( textid )匹配。

是一个人使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM