我在ASP.NET MVC应用程序中有一个表,我希望它是可排序的(服务器端)并且可以使用AJAX过滤.我希望它在其他地方使用起来相当容易,并且不想将排序和过滤硬编码到查询表达式中,所以我找到了一种动态构建表达式的方法,我找到的最好的方法是使用Dynamic LINQ .
来自以下URL的用户输入直接插入到动态Where或OrderBy中.
/Orders?sortby=OrderID&order=desc&CustomerName=Microsoft
这将导致两个表达式:
OrderBy("OrderID descending") Where(@"CustomerName.Contains(""Microsoft"")")
虽然我明白它不会直接在数据库中抛出,并且在这里插入直接的SQL将无法工作,因为它无法反映到属性中,并且它是类型安全的所有,我想知道是否有人比我更有创意无论如何都可以找到一种方法来利用它.我能想到的一个漏洞是可以对表中不可见的属性进行排序/过滤,但这并不是有害的,因为它们仍然无法显示,并且可以通过散列来防止它.
我允许直接用户输入的唯一方法是使用OrderBy和Where.
只是确定,谢谢:)
由于LINQ to SQL使用类型安全的数据模型类,因此默认情况下会受到SQL注入攻击的保护.LINQ to SQL将根据基础数据类型自动编码值.
(c)ScottGu
但是你仍然可以在那里"除以零",因此建议处理所有意外异常并限制有效条目的长度,JIC
嗯......我刚刚发现Dynamic Linq至少有一个问题.只需执行此代码段1000次,并注意CPU和内存消耗量的增加(为拒绝服务攻击创建一种简单的方法):
var lambda = DynamicExpression .ParseLambda("Customer=string.Format(\"{0,9999999}"+ "{0,9999999}{0,9999999}{0,9999999}{0,9999999}\",Customer)") .Compile(); var arg = new Order { Total = 11 }; Console.WriteLine(lambda(arg));
我写了一篇博文.
只是一个想法,但你看过ADO.NET数据服务?这提供了一个支持REST的API,就像上面一样,内置了许多标准的LINQ功能.
我想不出有兴趣的动态LINQ利用我的头顶部,但如果这是我,我会至少白名单成员(OrderID
,CustomerName
,等) -但我大概写了Expression
直接的逻辑; 如果你只支持直接属性,这并不是特别难.
例如,这是Where
(使用您的Contains
逻辑):
static IQueryableWhere (this IQueryable source, string member, string value) { var param = Expression.Parameter(typeof(T), "x"); var arg = Expression.Constant(value, typeof(string)); var prop = Expression.PropertyOrField(param, member); MethodInfo method = typeof(string).GetMethod( "Contains", new[] { typeof(string) }); var invoke = Expression.Call(prop, method, arg); var lambda = Expression.Lambda >(invoke, param); return source.Where(lambda); }
我之前已经介绍OrderBy
过,这里.