【问题标题】:How can I add multiple Get actions with different input params when working RESTFUL?使用 RESTFUL 时,如何添加具有不同输入参数的多个 Get 操作?
【发布时间】:2015-05-13 11:00:46
【问题描述】:

我正在尝试找出在 REST 控制器中拥有多个 Get 操作的最佳方式。

我想做这样的事情:

按 ID 获取:

public ResponseType Get(Guid id)
{
   // implementation
}

通过枚举类型获取:

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 创建多个控制器 - 但这似乎更错误。

第三种解决方法是使用具有以下状态的输入参数处理一个 Get 操作:

public ResponseType Get(ReqeustObj obj)
{
   switch(obj.RequestType)
   {
        case RequestType.GetById:
        // etc...
   }
}

无论如何,我想知道在 REST (WebApi) 中执行类似操作的最佳方法是什么。

【问题讨论】:

    标签: asp.net rest asp.net-web-api


    【解决方案1】:

    正如你现在,当 Web API 需要选择一个动作时,如果你没有在路由中指定动作名称,它会查找名称以方法名称开头的动作,在这种情况下是 GET。所以在你的情况下,它会找到多种方法。

    但它也尝试匹配参数。因此,如果您将参数作为 url(路由参数)或查询字符串的一部分包含在内,则操作选择器将能够选择一种可用的方法。

    如果您没有指定参数或在 url(甚至在查询字符串中)指定 id,它应该调用第一个重载。如果像这样在查询字符串中添加第二个动作的参数名称:?type=VALUE 应该选择对应的重载,以此类推。

    问题是参数名称必须不同,否则将无法在所有重载中选择一个。

    例如,如果您在浏览器中使用 cmets 中的 url,您将看到如何选择正确的方法:

    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" 的路由。这样可以避免使用查询字符串

    【讨论】:

    • @JotaBa - 这是不正确的。我虽然会尝试匹配参数并选择正确的操作,但即使参数名称和类型完全不同,它也不会这样做。
    • 不,不!这不是不正确的。请创建一个空的 Web API 项目并将代码粘贴到我更新的答案中。您可以在浏览器中测试 cmets 中的 url,您将看到它是如何工作的,没有问题
    • 我想你有一些冲突的方法。尝试只留下一个,测试它是否真的有效,然后一一取消注释,直到找到问题为止。还要确保您拥有默认的 Web API 路由。
    • @JotBe - 我不在有开发环境的电脑附近,但我相信你 - 我的 End 可能存在其他路由的特定问题。感谢您的回答 - 我觉得很愚蠢,因为您的回答是我的第一种方法,我认为查询字符串匹配是您可以依赖的东西,这就是我认为它不起作用的原因。
    • 不要相信我,相信我的 VS ;) 你让我怀疑,我创建了一个空的 Web API 项目并包含代码,对其进行测试,然后将其复制粘贴到答案中。顺便说一句,api/Testapi/Test/5 的前两种方法是在您添加新的 Web API 控制器时直接由 VS 搭建的,并且它们从一开始就运行良好。我添加了其他操作以完全确定我的解释是正确的。正如我在之前评论中告诉你的,你可以查看路由配置,然后对所有动作进行评论,最后取消注释并逐个测试,直到发现冲突
    猜你喜欢
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-11-04
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2017-11-06
    相关资源
    最近更新 更多