在Web Api中,如何使用两个get方法指定两个单独的路由到一个控制器而不使用属性?

时间:2014-12-11 18:32:24

标签: c# asp.net asp.net-web-api routing asp.net-web-api-routing

我有一个带有两个Get方法的帐户控制器,一个获取所有帐户并且不接受任何输入,另一个接受Id int并返回该特定帐户。

项目限制是我们不能将id作为默认路由上的可选参数,而是需要通过不同路由访问get-​​one-account和get-all-accounts,我们可以&# 39;使用属性路由。所以我们的路线配置目前看起来像这样:

config.Routes.MapHttpRoute("AccountWithId", "api/account/{id}", new { action = "Get", id = RouteParameter.Optional }
                , new { httpMethod = new HttpMethodConstraint(HttpMethod.Get), id = @"\d+" });

config.Routes.MapHttpRoute("Default", "api/{controller}");

我在AccountController上的两个Get方法如下所示:

public IHttpActionResult Get()
        {
            IList<AccountDto> users = m_service.Get();

            return Ok(users);
        }

        public IHttpActionResult Get(int accountId)
        {
            AccountDto user = m_service.Get(accountId);

            return Ok(user);
        }

但是当我通过我的自定义路由调用我的测试中的get参数并调试如下所示时,它仍然会触及不带一个id参数并返回全部的Get方法。

var url = "http://test/api/account/" + accountId;

var response = await m_server.HttpClient.GetAsync(url);

知道为什么吗?

1 个答案:

答案 0 :(得分:2)

我在这里可以看到很多问题。

你的第一条路线没有指定默认控制器,我很惊讶你发送一个accountid时没有得到404.

其次,如果id参数是可选的,则正则表达式应为\ d *而不是\ d +。

第三,操作中的参数名称应与路由参数匹配,因此应将accountId更改为id。

尝试使用此路线:

config.Routes.MapHttpRoute("AccountWithId",
    "api/account/{id}",
    new { controller = "Account", action = "Get", id = RouteParameter.Optional },
    new { httpMethod = new HttpMethodConstraint(HttpMethod.Get), id = @"\d*" }
);

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

然后将您的操作签名更改为:

public IHttpActionResult Get()
{
    ...
}

public IHttpActionResult Get(int id)
{
    ...
}