我正在试图找出在REST控制器中进行多个Get
操作的最佳方法。
我想做这样的事情:
获取身份证明:
public ResponseType Get(Guid id)
{
// implementation
}
Get By Enum Type:
public ResponseType Get(EnumType type)
{
// implementation
}
获取其他枚举类型:
public ResponseType Get(OtherEnumType otherType)
{
// implementation
}
等。
现在,当我这样做时,我收到下一条错误消息:
Multiple actions were found that match the request
我理解为什么我会得到这个消息而我正在考虑如何做出类似的事情(我想坚持使用REST)。
我知道我可以添加这样的路线:
routeTemplate: "api/{controller}/{action}/{id}"
但是我需要更改动作名称和网址 - 当我们谈论休息时,这似乎是一种解决方法。
我想到的另一件事是用一个Get
创建多个控制器 - 但这似乎甚至是wronger。
第三种解决方法是使用具有状态的输入参数来处理一个Get动作:
public ResponseType Get(ReqeustObj obj)
{
switch(obj.RequestType)
{
case RequestType.GetById:
// etc...
}
}
无论如何,我想知道在REST(WebApi)中做最好的方法是什么。
答案 0 :(得分:1)
就像你现在一样,当Web API需要选择一个动作时,如果你没有在路径中指定动作名称,它会查找名称以方法名称开头的动作,在这种情况下为GET。所以在你的情况下,它会找到多种方法。
但它也尝试匹配参数。因此,如果您将参数作为url(路由参数)或查询字符串的一部分包含在内,则操作选择器将能够选择一种可用的方法。
如果你没有在url中指定参数或指定id(甚至在查询字符串中),它应该调用第一个重载。如果在查询字符串中添加第二个操作的参数名称,如下所示:?type=VALUE
它应该选择相应的重载,依此类推。
问题是参数名称必须不同,否则将无法在所有重载中选择其中一个。
例如,如果您在浏览器的评论中使用网址,则会看到如何选择正确的方法:
public class TestController : ApiController
{
// GET api/Test
public string Get()
{
return "without params";
}
// GET api/Test/5
public string Get(int id)
{
return "id";
}
// GET api/Test?key=5
public string Get(string key)
{
return "Key";
}
// GET api/Test?id2=5
public string Get2(int id2)
{
return "id2";
}
}
注意:您也可以使用路径约束来调用不同的方法,而不使用查询字符串参数,而是使用不同的约束定义不同的路径参数名称。例如,您可以为id
添加约束,仅接受数字" \ d +"然后是第二条接受" key"对于所有其他情况。这样就可以避免使用查询字符串