当 Uri 转义 & 符号时 OData 过滤器选项失败
OData filter options fail when Uri has escaped ampersand
我目前正在使用 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生成的link是经过编码的,比如下一页link:
OData 似乎不介意 %20 (space) 可以正常工作,但 $skip 实际上会被忽略,因为转义的 & 符号 (&) 如果您只是将它更改为真正的 & 符号(&) 它工作正常。
有办法解决这个问题吗?这似乎是 OData 的问题。
参考这里是我如何映射我的路线:
#pragma warning disable CS0618 // OData v3 route mapping.
config.Routes.MapODataRoute(
routeName: "odata",
routePrefix: "odata",
model: model);
#pragma warning restore CS0618
我没有做任何定制。
更新:
当我将 ACCEPT header 设置为 XML 时,我得到:
当我将 ACCEPT header 设置为 JSON 时,我得到:
odata.nextLink": "http://webapi.mydlweb.com/api/test/odata/v3/Checks?$filter=StoreId%20eq%2040&pagesize=1&$skip=1"
根据下面的评论,正确生成了 JSON link。我可以单击它并且它可以工作,因为&符号未编码。但是 XML link 确实对 & 符号进行了编码,因此导致它无法工作。那么编码 XML 正常吗?那么客户端如何知道 "unencode" 的哪些和号以及哪些要保留编码?例如,如果您在过滤器中使用和号(不是分隔查询字符串),那么它确实需要编码。
更新 2:
我猜它是 XML 编码,这就是它的方式。
您不能对查询字符串中的 & 符号进行转义并期望它在查询字符串中表现得像未转义的 & 符号。这与 odata 没有任何关系,只是正常的查询字符串行为。通过转义它,解析器不会将其解释为 key/value 对的定界符,而是将其解释为值中的文字 & 符号。
示例:此 google 搜索有效:
https://www.google.com/search?safe=off&q=test
但是,这个不是:
https://www.google.com/search?safe=off%26q=test
我目前正在使用 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生成的link是经过编码的,比如下一页link:
OData 似乎不介意 %20 (space) 可以正常工作,但 $skip 实际上会被忽略,因为转义的 & 符号 (&) 如果您只是将它更改为真正的 & 符号(&) 它工作正常。
有办法解决这个问题吗?这似乎是 OData 的问题。
参考这里是我如何映射我的路线:
#pragma warning disable CS0618 // OData v3 route mapping.
config.Routes.MapODataRoute(
routeName: "odata",
routePrefix: "odata",
model: model);
#pragma warning restore CS0618
我没有做任何定制。
更新:
当我将 ACCEPT header 设置为 XML 时,我得到:
当我将 ACCEPT header 设置为 JSON 时,我得到:
odata.nextLink": "http://webapi.mydlweb.com/api/test/odata/v3/Checks?$filter=StoreId%20eq%2040&pagesize=1&$skip=1"
根据下面的评论,正确生成了 JSON link。我可以单击它并且它可以工作,因为&符号未编码。但是 XML link 确实对 & 符号进行了编码,因此导致它无法工作。那么编码 XML 正常吗?那么客户端如何知道 "unencode" 的哪些和号以及哪些要保留编码?例如,如果您在过滤器中使用和号(不是分隔查询字符串),那么它确实需要编码。
更新 2: 我猜它是 XML 编码,这就是它的方式。
您不能对查询字符串中的 & 符号进行转义并期望它在查询字符串中表现得像未转义的 & 符号。这与 odata 没有任何关系,只是正常的查询字符串行为。通过转义它,解析器不会将其解释为 key/value 对的定界符,而是将其解释为值中的文字 & 符号。
示例:此 google 搜索有效:
https://www.google.com/search?safe=off&q=test
但是,这个不是:
https://www.google.com/search?safe=off%26q=test