如何转义要在OData查询中使用的单引号?

时间:2010-10-20 15:11:00

标签: c# odata

我正在使用OData来查询我的数据库。当“adapterName”只包含文本时,以下代码行正常工作。

ds.query('/DataAdapters?$filter=Name eq \'' + adapterName + '\'', ifmgr_CreateAdapter_Step1, onGenericFailure, '');

如果“adapterName”包含单引号,则会失败。我尝试使用以下代码转义单引号:

adapterName = adapterName.replace(/\'/g, '\\\'');

虽然这正确地逃避了用户定义的文本,但该功能仍然失败。谁能告诉我查询中文本的格式是什么?

5 个答案:

答案 0 :(得分:88)

实际上%27不是解决方案。正确的转义方法是将两个单引号放入字符串而不是一个。 在示例"o''clock"

答案 1 :(得分:6)

我想稍微扩展一下这个问题,以便它也适用于调用oData服务操作操作。答案的答案是正确的,但有一个特定的顺序,其中服务操作的参数必须编码。

oData服务操作接收基本类型参​​数,其中字符串包含在'这样一个有效的网址(预编码)将是这样的

AddString值=' 2 O''时钟'

这将导致服务器看到

AddString值='○'

'时钟'

将生成"错误请求 - 查询语法错误。"

要纠正这个问题,你必须双倍地逃避'并在插入网址之前对其进行UrlEncode。

不要对网址进行UrlEncode。

这是一个可行的例子。

// value passed as "o'clock"
public async Task AddString(string value)
{
    // Escape ' with '' and UrlEncode value
    value = HttpUtility.UrlEncode(value.Replace("'", "''"));

    string url = String.Format("AddString?value='{0}'", value);

    // No need to UrlEncode url here as dynamic content has already been escaped 

    // Execute .....
}

[WebGet]
public void AddString(string value) 
{
    // here value will be "o'clock"
}

答案 2 :(得分:0)

当使用wit substringof时,需要通过4而不是1个撇号进行转义:

a'b -> $filter=(substringof('a''''b', FirstName))

答案 3 :(得分:0)

它实际上是在oData文档中描述的:http://docs.oasis-open.org/odata/odata/v4.01/cs01/part2-url-conventions/odata-v4.01-cs01-part2-url-conventions.html#sec_URLComponents

  

例如,这些规则之一是字符串文字中的单引号表示为两个连续的单引号。

     

示例3:有效的OData URL:

     

http://host/service/People('O'Neil')

     

http://host/service/People(%27O%27%27Neil%27)

     

http://host/service/People%28%27O%27%27Neil%27%29

     

http://host/service/Categories('Smartphone%2FTablet')

     

示例4:无效的OData URL:

     

http://host/service/People('O'Neil')

     

http://host/service/People('O%27Neil')

     

http://host/service/Categories(“智能手机/平板电脑”)

     

第一个和第二个示例无效,因为字符串>文字中的单引号必须表示为两个连续的单引号。第三个示例无效,因为正斜杠被解释为路径段分隔符和类别(“智能手机不是有效的OData路径段,而Tablet也不是”)。

答案 4 :(得分:-1)

而不是使用$ filter = Title eq' text'

我正在使用oData startswith()函数。

$ filter = startswith(Title,key)

然后我尽可能多地传递密钥。

var pos = key.indexOf("'");
if(pos > -1) {
key = key.substring(0, pos);
}