我在ASP.NET WebApi 2 OData中公开了数据库中的两个实体:service 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控制器中的代码,因此可以看到受限制的员工记录。什么是阻止这种情况发生的好方法?
答案 0 :(得分:0)
在这种情况下:http://localhost/odata/Activities?$ expand = OpenedBy
我认为您应该更改ActivitiesController中的代码, $ expand 会点击获取活动方法。
如果您不想一直展开OpenedBy,可以添加一个属性: 的 [NotExpandable] 强>
希望这有助于:)
答案 1 :(得分:0)
既然你说“我注意到如果我运行查询”,我会觉得这是一个副作用,你很乐意在所有情况下限制。如果是这种情况this article by Mike Wasson可能对您有用。
在那篇文章中,他提出了两种限制odata访问属性的方法:
我没有尝试第一个,我不确定你需要做哪个命名空间或库,但在问题的情况下它看起来像这样:
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);
我以这种方式限制了一些导航集合,并且效果非常好。