【问题标题】:OData filter options fail when Uri has escaped ampersand当 Uri 已转义 & 符号时,OData 筛选器选项失败
【发布时间】:2018-02-17 14:52:47
【问题描述】:

我目前正在使用 OData v3,但这似乎在 OData v4 中也失败了(只是不同)。

假设我有以下 Uri:
http://myurl.com/odata/SomeEndpoint?$filter=FieldId eq 1&$top=10

完美,在 Postman 或浏览器中输入,效果很好。但如果我对 Uri 进行编码,它就会失败。

HTML 编码:
http://myurl.com/odata/SomeEndpoint?$filter=FieldId eq 1&$top=10

转义字符之前的所有内容都将应用于查询(因此 $filter 仍然有效),但转义字符之后的所有内容都将被忽略(不应用 $top)。

URI 编码(我都试过了):
http://myurl.com/odata/SomeEndpoint?$filter=FieldId eq 1%26$top=10 http://myurl.com/odata/SomeEndpoint?$filter=FieldId eq 1%26%$top=10

在尝试应用带有以下错误的查询选项时,两者都会导致 OData 引发异常(因为这是来自内存,所以解释一下):

'&' is in invalid character in query string.
$filter=FieldId eq 1&$top=10

如您所见,这是不受欢迎的问题。如果我的客户在发送请求之前对他们的 Uri 进行编码,它将不起作用。另外,OData在结果中生成的链接也是经过编码的,比如下一页链接:

OData 似乎并不介意 %20 (空格)可以正常工作,但是 $skip 实际上会被忽略,因为如果您只是将其更改为真正的 & 符号 (&) 它可以正常工作.

有没有办法解决这个问题?这似乎是 OData 的问题。

以下是我绘制路线的方式供参考:

#pragma warning disable CS0618 // OData v3 route mapping.
config.Routes.MapODataRoute(
    routeName: "odata",
    routePrefix: "odata",
    model: model);
#pragma warning restore CS0618

我没有做任何定制的事情。

更新:
当我将我的 ACCEPT 标头设置为 XML 时,我得到:

当我将我的 ACCEPT 标头设置为 JSON 时,我得到:
odata.nextLink": "http://webapi.mydlweb.com/api/test/odata/v3/Checks?$filter=StoreId%20eq%2040&pagesize=1&$skip=1"

根据下面的评论,正确生成了 JSON 链接。我可以单击它并且它可以工作,因为&符号未编码。然而,XML 链接确实对 & 符号进行了编码,因此导致它无法工作。那么在编码 XML 时这是正常的吗?那么客户端如何知道哪些“与”符号要“取消编码”以及哪些要保留编码呢?例如,如果您在过滤器中使用 & 符号(而不是分隔查询字符串),那么它确实需要编码。

更新 2: 我猜是XML编码,就是这样。

【问题讨论】:

  • 乍一看,它似乎应该是这样工作的。通过转义 & 符号,您告诉解析器不要将其解释为查询字符串分隔符,而是解释为文字值。因此,在您的示例中,您似乎正在尝试将与号(以及查询字符串的请求)作为 $filter 的一部分。
  • 过滤器应该只是 $filter=StoreId eq 40 其余的如“$skip”或“pagesize”不是过滤器的一部分,而是其他查询字符串

标签: c# asp.net-web-api odata urlencode


【解决方案1】:

您不能对查询字符串中的 & 符号进行转义,并期望它的行为类似于查询字符串中未转义的 & 符号。这与 odata 没有任何关系,只是正常的查询字符串行为。通过转义它,解析器不会将其解释为键/值对的分隔符,而是作为值中的文字 & 符号。

示例:此 google 搜索有效:

https://www.google.com/search?safe=off&q=test

但是,这个没有:

https://www.google.com/search?safe=off%26q=test

【讨论】:

  • 这是有道理的,但自动生成的 XML 格式的链接已对其进行了编码。查看我的更新。
  • 当你说“我猜那是 XML 编码”时,你是对的。从技术上讲,您应该使用 XML 解析器读取 XML,该解析器将解码该值并为您提供“真实”值。挑战在于,大多数 XML 都非常易于阅读,以至于您不必对它进行实际解码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 2011-04-22
相关资源
最近更新 更多