限制对OData$expand操作中数据的访问
本文关键字:数据 访问 操作 expand OData | 更新日期: 2024-10-23 21:15:38
我的数据库中有两个实体在ASP.NET WebApi 2 OData中公开:服务Employee
和Activity
。为了简单起见,我们假设它们看起来是这样的:
public class Employee {
public int Id { get; set; }
public string Type { get; set; }
}
public class Activity {
public int Id { get; set; }
public int EmployeeId { get; set; }
public virtual Employee OpenedBy { get; set; }
}
请注意,OpenedBy
属性对应于导航属性,例如,我可以运行以下OData查询:
GET http://localhost/odata/Activities?$expand=OpenedBy
我想阻止某些Employee类型显示在OData中。假设我不能在数据源上执行此操作,所以我必须在代码中执行此操作。
到目前为止,我所做的是在EmployeesController(继承自EntitySetController)中阻止这些类型:
[Queryable]
public override IQueryable<Employee> Get() {
return dbContext.Employees.Where(e => e.Type != "Restricted").AsQueryable();
}
[Queryable]
protected override Employee GetEntityByKey([FromODataUri] int key) {
var employee = dbContext.Employees.Find(key);
if (employee == null || employee.Type == "Restricted") {
throw new ODataException("Forbidden");
}
return employee;
}
这很好用。然而,我注意到,如果我运行查询:
GET http://localhost/odata/Activities?$expand=OpenedBy
我没有命中Employees控制器中的代码,因此受限制的员工记录是可见的。防止这种情况发生的好方法是什么?
在这种情况下:http://localhost/odata/Activities?$expand=由打开
我认为您应该更改ActivityController中的代码,$expand将在那里点击Get-Activity方法。
如果不想一直展开OpenedBy,可以添加一个属性:[NotExpandable]
希望这能有所帮助:)
因为你说"我注意到如果我运行查询",我得到的印象是,这是一个副作用,你很乐意在任何情况下限制它。如果是这样的话,Mike Wasson的这篇文章可能对你有用。
在那篇文章中,他提出了两种限制odata访问属性的方法:
- 模型上的属性
- 以编程方式将其从EDM中删除
我没有尝试第一个,我不确定你需要使用哪个命名空间或库,但是,在这个问题的情况下,它看起来是这样的:
public class Activity {
public int Id { get; set; }
public int EmployeeId { get; set; }
[IgnoreDataMember]
public virtual Employee OpenedBy { get; set; }
}
我使用了第二种方法,对于问题中给出的例子,这看起来像这样:
var activities = modelBuilder.EntitySet<Activity>("Activities");
activities.EntityType.Ignore(a => a.OpenedBy);
我已经用这种方式限制了一些导航集合,它运行得很好。