这个问题可以回答数百次,但我找不到合适的资源。在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的基本概念吗? (我想是的)
答案 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的方式构建您的网址空间
所以方法将是GetById
,GetByName
,然后传递查询字符串中的参数以匹配正确的操作(BTW不确定您的案例之间的区别是GetById
和FindById
如果它们没有真正不同,可以考虑只保留其中一个。)
您可以坚持使用默认路线,您的请求将如下所示:
/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+" }
);