WebApi2官网学习记录---OData中的查询

EMD安全

  查询语法是基于entity data model(EDM),不是基于底层的model类型,可以从EDM排除一个属性,这样这个属性在client就不能被查询了。

有两种方式可以从EDM中排除一个属性

第一种使用 [IgnoreDataMember]特性

public class Employee

{

    public string Name { get; set; }

    public string Title { get; set; }
//当应用于类型的成员时,指定该成员不是数据协定的一部分且没有进行序列化 命名空间System.Runtime.Serialization [IgnoreDataMember]
public decimal Salary { get; set; } // Not visible in the EDM }

第二种方式以编程方式从EDM中排除属性 

var employees = modelBuilder.EntitySet<Employee>("Employees");

employees.EntityType.Ignore(emp => emp.Salary);

安全查询

     [Queryable]特性是一个action过滤器支持解析、验证以及应用查询,过滤器将查询选项转为一个LINQ表达式。

  Web API支持以下OData查询选项:  

WebApi2官网学习记录---OData中的查询

为了使用OData的查询,必须显示指定查询可用。可以在全局进行配置或在指定的控制器或action上。

public static void Register(HttpConfiguration config)

{   

    config.EnableQuerySupport();

    // ...

}
public class ProductsController : ApiController

{

    [Queryable]

    IQueryable<Product> Get() {}

}

限制查询

  为了安全或性能方面的考虑,可能需要限制一些操作。Queryable]特性有一些内建的属性可以实现这一点。如下所示:

//仅允许$skip与$top操作

[Queryable(AllowedQueryOptions=AllowedQueryOptions.Skip | AllowedQueryOptions.Top)]

//在指定属性上进行排序,对于在数据库中没有索引的字段会禁止排序操作的

[Queryable(AllowedOrderByProperties="Id")] 

//仅允许“eq”这种逻辑操作

[Queryable(AllowedLogicalOperators=AllowedLogicalOperators.Equal)]

//禁止所有的算术操作

[Queryable(AllowedArithmeticOperators=AllowedArithmeticOperators.None)]

  可以通过构造一个QueryableAttribute的实例在定义全局查询过滤

var queryAttribute = new QueryableAttribute()

{

    AllowedQueryOptions = AllowedQueryOptions.Top | AllowedQueryOptions.Skip,

    MaxTop = 100

};

                

config.EnableQuerySupport(queryAttribute);

直接调用查询选项

  不使用[Queryable]特性,可以在controller中直接调用查询选项,这要做需要在方法中添加一个ODataQueryOptions参数

public IQueryable<Product> Get(ODataQueryOptions opts)

{

    var settings = new ODataValidationSettings()

    {

        // Initialize settings as needed.

        AllowedFunctions = AllowedFunctions.AllMathFunctions

    };



    opts.Validate(settings);



    IQueryable results = opts.ApplyTo(products.AsQueryable());

    return results as IQueryable<Product>;

}

查询验证

 [Querable]特性在执行之前就验证查询选项,验证步骤在QueryableAttribute.ValidateQuery 方法中执行,可以自定义验证过程。如下所示:

WebApi2官网学习记录---OData中的查询
 1 public class MyOrderByValidator : OrderByQueryValidator

 2 {

 3     // Disallow the 'desc' parameter for $orderby option.

 4     public override void Validate(OrderByQueryOption orderByOption,

 5                                     ODataValidationSettings validationSettings)

 6     {

 7         if (orderByOption.OrderByNodes.Any(

 8                 node => node.Direction == OrderByDirection.Descending))

 9         {

10             throw new ODataException("The 'desc' option is not supported.");

11         }

12         base.Validate(orderByOption, validationSettings);

13     }

14 }

15 

16 public class MyQueryableAttribute : QueryableAttribute

17 {

18     public override void ValidateQuery(HttpRequestMessage request, 

19         ODataQueryOptions queryOptions)

20     {

21         if (queryOptions.OrderBy != null)

22         {

23             queryOptions.OrderBy.Validator = new MyOrderByValidator();

24         }

25         base.ValidateQuery(request, queryOptions);

26     }

27 }

28 

29 // Globally:

30 config.EnableQuerySupport(new MyQueryableAttribute());

31 

32 // Per controller:

33 public class ValuesController : ApiController

34 {

35     [MyQueryable]

36     public IQueryable<Product> Get()

37     {

38         return products.AsQueryable();

39     }

40 }
View Code

 如果直接使用ODataQueryOptions 可以设置验证器  

public IQueryable<Product> Get(ODataQueryOptions opts)

{

    if (opts.OrderBy != null)

    {

        opts.OrderBy.Validator = new MyOrderByValidator();

    }



    var settings = new ODataValidationSettings()

    {

        // Initialize settings as needed.

        AllowedFunctions = AllowedFunctions.AllMathFunctions

    };



    // Validate

    opts.Validate(settings);



    IQueryable results = opts.ApplyTo(products.AsQueryable());

    return results as IQueryable<Product>;

}

Note:在新版本的WebAPI中[Queryable]特性已经被否决,使用[EnableQuery]特性

你可能感兴趣的:(Data)