具有不同参数名称的Web api路由方法

时间:2014-02-06 03:37:21

标签: asp.net-mvc-4 asp.net-web-api asp.net-web-api-routing

这个问题可以回答数百次,但我找不到合适的资源。在WebApi项目(由VS提供的默认项目)中,我有如下的ValuesController。

   public string Get(int id)
    {
        return "value";
    }

    [HttpGet]
    public string FindByName(string name)
    {
        return name;
    }

    [HttpGet]
    public string FindById(int id)
    {
        return id.ToString();
    }

在WebApiConfig.cs中,我有以下路线映射。

 config.Routes.MapHttpRoute(
              name: "actionApiById",
              routeTemplate: "api/{controller}/{action}/{Id}",
              defaults: new { action = "FindById", Id = RouteParameter.Optional }
              );


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

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

现在,当我在浏览器中尝试时,只有FindById()动作正常。为什么其余的api调用返回“没有找到与请求匹配的HTTP资源

如何让所有三种方法都有效?不使用AttributeRouting。我缺乏web api的基本概念吗? (我想是的)

3 个答案:

答案 0 :(得分:4)

AS我们都知道REST是基于资源的,它使用URL标识资源,因此在REST服务中将允许不超过一个具有相同参数的方法,但是在MVC 5 Web Api方法级别路由中有解决方法

以下是您可以执行此操作的示例:

[HttpGet]
[Route("api/search/FindByName/{name}")]
FindByName(string name)
{
}

[HttpGet]
[Route("api/search/FindById/{name}")]
FindById(int searchId)

注意:"搜索"是控制器名称。

如果需要更多说明,请告知。

答案 1 :(得分:2)

一般情况下,您不希望像示例所示的每个操作都有一个路径。随着您的应用程序的增长,这将很快失控。

另外,请考虑以看起来只是RESTfull的方式构建您的网址空间

所以方法将是GetByIdGetByName,然后传递查询字符串中的参数以匹配正确的操作(BTW不确定您的案例之间的区别是GetByIdFindById如果它们没有真正不同,可以考虑只保留其中一个。)

您可以坚持使用默认路线,您的请求将如下所示:

/api/controller/345 or /api/controller?name=UserName or /api/controller?SearchId=345 (assuming search was indeed a different behavior)

然后方法签名:

Get(int id)
{
}

[HttpGet]
FindByName(string name)
{
}

[HttpGet]
FindById(int searchId)
{
}

答案 2 :(得分:1)

您的actionApiById路由也与actionApi路由匹配,因为您的ID是整数,请尝试使用这样的约束。

config.Routes.MapHttpRoute(
              name: "actionApiById",
              routeTemplate: "api/{controller}/{action}/{Id}",
              defaults: new { action = "FindById", Id = RouteParameter.Optional }
              constraints: new {Id = @"\d+" }
              );