.net 在DataTable筛选器表达式中转义字符的正确方法

.net 在DataTable筛选器表达式中转义字符的正确方法,.net,ado.net,.net,Ado.net,我想知道是否有一个函数可以正确地转义过滤器表达式的字符串文字。e、 g: DataTable.Select(String.Format("[name] = '{0}'", MyName)) 如果MyName包含“”或许多其他关键字符,则会生成异常。指示应该正确转义这些字符,但是在如何进行转义方面存在一些混乱 如文档所示,我已尝试将“替换为”和[”],但查询仍然失败。如果我将“替换为两个单引号”,则查询有效。通过将单引号加倍为“”来转义单引号。通过在[]中换行来转义*%[]个

我想知道是否有一个函数可以正确地转义过滤器表达式的字符串文字。e、 g:

DataTable.Select(String.Format("[name] = '{0}'", MyName))
如果MyName包含“”或许多其他关键字符,则会生成异常。指示应该正确转义这些字符,但是在如何进行转义方面存在一些混乱


如文档所示,我已尝试将“替换为”和[”],但查询仍然失败。

如果我将“替换为两个单引号”,则查询有效。

通过将单引号加倍为“”来转义单引号。通过在[]中换行来转义*%[]个字符。 e、 g

私有字符串EscapeLikeValue(字符串值)
{
StringBuilder sb=新StringBuilder(值.Length);
for(int i=0;i
感谢

//
///如果LIKE子句中的模式包含这些特殊字符中的任意一个*%[],则这些字符必须在括号[]中转义,如[*]、[%]、[[]或[]]。
///如果模式不在like子句中,则可以传递valueIsForLIKEcomparison=false以不转义括号。
///示例:
///-strFilter=“[Something]如“%”+DataTableHelper.EscapeLikeValue(filterValue)+“%”;
/// 
/// http://www.csharp-examples.net/dataview-rowfilter/
/// 
///与filterValue类似。这不应该是整个筛选器字符串…只是要比较的部分。
///是否在类似比较中使用filterValue。
/// 
公共静态字符串EscapeFilterValue(字符串filterValue,布尔值为ForLikeComparison=true)
{
字符串lb=“~~左括号~~”;
字符串rb=“~~右括号~~”;
filterValue=filterValue.Replace(“[”,lb)。Replace(“]”,rb)。Replace(“​*", "[*​]").替换(“%”,“[%]”。替换(“”,“”);
如果(值为Forlike比较)
{
filterValue=filterValue.Replace(lb,“[[]”)。Replace(rb,“[]”);
}
其他的
{
filterValue=filterValue.Replace(lb,“[”)。Replace(rb,“]);
}
返回filterValue;
}

这甚至不是特定于数据表的,而是在SQL中执行此操作的一般方法。:-)虽然我使用参数化查询,所以在SQL中不需要这样做。但我明白了。如果使用参数化查询,无论如何都是安全的,但是TableFilter是SQL的内存子集,由WHERE子句组成,必须符合SQL语法规则。它只是一个字符串,所以这里没有参数。这就是为什么这个额外的step必须采取。我承认我希望这个问题的答案是“参数化版本的
DataTable.Select()
is…”,但似乎MS决定每个程序员都需要重新实现值转义。这对我来说不适用于包含方括号的字符串。“字符串”图像[Three Up]正在由筛选器“entryBlockName='Images[Three Up]'”而不是筛选器“entryBlockName='Images[[]Three Up[]]”找到啊。括号的转义仅当筛选器是LIKE子句时才出现。而不是当它是=子句时。我也面临同样的问题,在我的情况下,我只想检查是否存在任何具有给定名称的行,因此我被用于LINQ。
Data.AsEnumerable().Where(row=>Convert.ToString(row[“name”]).ToLower().Equals(newName.ToLower()).any()
这是如何安全的?它似乎用一个漏洞换了一个更模糊的漏洞。你说的是什么漏洞?如果你是指将用户输入传递到函数中,那么就不要传递用户输入。只是说,作为这种转义的主要驱动因素,通常是bobby tables类型的攻击。除非你意识到当然,除了强制复合语句的语法正确性之外,实际的缺陷是使用了“神奇字符串常量”这本身就是一个有效的输入。简单地说:使用你答案的代码作为你发布的函数的输入,它将返回一个不正确的输出:)是的,但这就是为什么我选择了一些不会在我的系统中使用的东西,除此之外的任何原因。“~~LeftBracket~~”。这是一种黑客行为,但它对我有效。
private string EscapeLikeValue(string value)
{
    StringBuilder sb = new StringBuilder(value.Length);
    for (int i = 0; i < value.Length; i++)
    {
        char c = value[i];
        switch (c)
        {
            case ']':
            case '[':
            case '%':
            case '*':
                sb.Append("[").Append(c).Append("]");
                break;
            case '\'':
                sb.Append("''");
                break;
            default:
                sb.Append(c);
                break;
        }
    }
    return sb.ToString();
}

public DataRow[] SearchTheDataTable(string searchText)
{ 
     return myDataTable.Select("someColumn LIKE '" 
                                 + EscapeLikeValue(searchText) + "'");
} 
   /// <summary>
    /// <para>If a pattern in a LIKE clause contains any of these special characters * % [ ], those characters must be escaped in brackets [ ] like this [*], [%], [[] or []].</para>
    /// <para>If the pattern is not in a like clause then you can pass valueIsForLIKEcomparison = false to not escape brackets.</para>
    /// <para>Examples:</para>
    /// <para>- strFilter = "[Something] LIKE '%" + DataTableHelper.EscapeLikeValue(filterValue) + "%'";</para>
    /// <para></para>
    /// <para>http://www.csharp-examples.net/dataview-rowfilter/</para>
    /// </summary>
    /// <param name="filterValue">LIKE filterValue. This should not be the entire filter string... just the part that is being compared.</param>
    /// <param name="valueIsForLIKEcomparison">Whether or not the filterValue is being used in a LIKE comparison.</param>
    /// <returns></returns>
    public static string EscapeFilterValue(string filterValue, bool valueIsForLIKEcomparison = true)
    {
        string lb = "~~LeftBracket~~";
        string rb = "~~RightBracket~~";
        filterValue = filterValue.Replace("[", lb).Replace("]", rb).Replace("​*", "[*​]").Replace("%", "[%]").Replace("'", "''");
        if (valueIsForLIKEcomparison)
        {
            filterValue = filterValue.Replace(lb, "[[]").Replace(rb, "[]]");
        }
        else
        {
            filterValue = filterValue.Replace(lb, "[").Replace(rb, "]");
        }

        return filterValue;
    }