2014-02-06 115 views
2

此问题可能已被答复了上百次,但我找不到合适的资源。在WebApi项目(VS提供的默认项目)中,我有如下的ValuesController。具有不同参数名称的Web api路由方法

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的基本概念吗? (我认为是)

+0

你的意思是你不能调用“Get”方法?如果是这样,请分享您从客户端调用方法的方式? – Thanigainathan

回答

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+" } 
      ); 
+0

我只是想通了...... – JenonD

2

一般而言,您不希望像您的样本建议一样采取行动。随着您的应用程序的增长,这将很快失去控制。

也可以考虑的方式,将寻找建立您的网址空间只是问题的REST

这样的方法将是GetByIdGetByName,然后传递参数的查询字符串匹配正确的行动(顺便说一句不知道的在你的情况下,差异在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) 
{ 
} 
4

大家都知道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) 

注:“搜索”是控制器的名字。

请让我们知道是否需要更多的澄清。

+0

是的,我喜欢这个解决方案,是我实施的,但我不知道这是否是好的做法? –

相关问题