【问题标题】:How to use complex parameters with Web API RESTful Get method如何通过 Web API RESTful Get 方法使用复杂参数
【发布时间】:2016-09-05 19:18:27
【问题描述】:

对于 RESTful API,我需要使用 get 来检索列表,但是我想传递以下一些复杂参数作为方法的输入。

{
  "Filters": [
    {
      "FieldName": "sample string 1",
      "FieldValue": "sample string 2"
    },
    {
      "FieldName": "sample string 1",
      "FieldValue": "sample string 2"
    }
  ],
  "SortField": "sample string 1",
  "SortValue": 0,
  "Page": 2,
  "PageSize": 3
}

由于我不能在 Get 方法中使用 RequestBody,因此如何传递参数,如果我将其设为 Post,它将不是 RESTful。

【问题讨论】:

  • 不使用 url 编码的查询还有一个问题,在响应中返回“下一个”链接并不容易(可能吗?)。

标签: json rest asp.net-web-api2


【解决方案1】:

我完全反对在 URI 的查询字符串中使用序列化 JSON,原因如下:

  1. 它使 URI 不可读(编码的括号和空格会生成可怕的查询字符串)
  2. 它使参数不可组合(要添加另一个“过滤器”,您必须取消对 JSON 的编码,将其反序列化为对象,添加新字段,然后再次序列化 + 编码)
  3. 它会无益地创建长 URI(再次说明,不必要的 JSON 编码部分会使查询字符串变长)

即使您可以将 POST 用于此目的,我相信如果您打算只查询数据而不修改数据,则继续使用 GET 在语义上更正确。

在您描述的许多情况下,我只是将复杂对象转换为单独的查询字符串参数,创建像这样的 URI:

http://myhost.com/query?filters.fieldName1=fieldValue1&filters.fieldName2=fieldValue2&sort=fieldName&sortDirection=asc&page=2&pageSize=3

您可以使用自定义ModelBinder 为包含任何数据的自定义Paging 对象轻松地在ASP.NET Web Api 2 中解析此查询字符串(我想您正在使用此框架,因为您的问题中有标签)您需要在服务器端执行查询。

作为一种替代方法,您可以考虑将这些参数放在自定义(或多个)请求标头中,然后在服务器端读取它们:

X-Query-Filter: FieldName1=FieldValue1&FieldName2=FieldValue2
X-Query-Sort: FieldName
X-Query-Sort-Direction: ASC
X-Query-Page: 2
X-Query-PageSize: 3

【讨论】:

    【解决方案2】:

    如果复杂的有效负载会超过 url 参数的可能大小,您可以将大型有效负载 POST 到 queries 端点,然后使用 URI 作为 GET 调用中的参数。

    这是两个调用,而不是一个,但在纯粹的意义上,允许在 GET 调用中使用二进制文件和 blob。除了特殊情况,我认为这是矫枉过正。

    如果 POST 有效,请使用它。

    【讨论】:

      【解决方案3】:

      通过 URI 中的过滤器:

       var encodedQueryString = encodeURIComponent(JSON.stringify({
            "Filters": [
              {
                "FieldName": "sample string 1",
                "FieldValue": "sample string 2"
              },
              {
                "FieldName": "sample string 1",
                "FieldValue": "sample string 2"
              }
            ],
            "SortField": "sample string 1",
            "SortValue": 0,
            "Page": 2,
            "PageSize": 3
          }))
          var url = example.com?filters="+encodedQueryString
          //http://www.example.com?filters=%7B%22Filters%22%3A%5B%7B%22FieldName%22%3A%22sample%20string%201%22%2C%22FieldValue%22%3A%22sample%20string%202%22%7D%2C%7B%22FieldName%22%3A%22sample%20string%201%22%2C%22FieldValue%22%3A%22sample%20string%202%22%7D%5D%2C%22SortField%22%3A%22sample%20string%201%22%2C%22SortValue%22%3A0%2C%22Page%22%3A2%2C%22PageSize%22%3A3%7D
      

      提琴手输出:

      【讨论】:

      • 好吧,我不知道你的确切情况,所以不,但它似乎确实是一个合法的 URL:freeformatter.com/url-parser-query-string-splitter.html
      • 问题是你没有给参数命名。 ?filters={encoded string} 将允许端点读取字符串,然后反序列化为对象。
      【解决方案4】:

      阅读 REST API using POST instead of GET 和其他人,似乎没有规范的 Restful 定义禁止使用 POST 来满足您的需求。

      在这种情况下,规则可能是“尽最大努力”。

      此外,由于您似乎同时拥有进程的主机端和客户端,因此没有太多理由避免使用 POST。

      从根本上说,没有简单的方法可以将序列化的 json 合并到 URL 中,而这正是 GET 所需要的。

      【讨论】:

      • 我的控制器启用了 CRUD 操作,该操作使用 Post 方法进行 Create 和 Get 来检索数据。但是,对于这种方法,我应该使用自定义 Post 方法
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 2012-12-19
      • 2014-10-14
      • 1970-01-01
      相关资源
      最近更新 更多