在OData $ expand操作中限制对数据的访问

时间:2015-03-07 16:29:33

标签: c# asp.net asp.net-web-api odata

我在ASP.NET WebApi 2 OData中公开了数据库中的两个实体:service EmployeeActivity。为简单起见,我们假设它们看起来像这样:

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控制器中的代码,因此可以看到受限制的员工记录。什么是阻止这种情况发生的好方法?

2 个答案:

答案 0 :(得分:0)

在这种情况下:http://localhost/odata/Activities?$ expand = OpenedBy

我认为您应该更改ActivitiesController中的代码, $ expand 会点击获取活动方法

如果您不想一直展开OpenedBy,可以添加一个属性:         的 [NotExpandable]

希望这有助于:)

答案 1 :(得分:0)

既然你说“我注意到如果我运行查询”,我会觉得这是一个副作用,你很乐意在所有情况下限制。如果是这种情况this article by Mike Wasson可能对您有用。

在那篇文章中,他提出了两种限制odata访问属性的方法:

  1. 您模特的属性
  2. 以编程方式将其从EDM中删除
  3. 我没有尝试第一个,我不确定你需要做哪个命名空间或库,但在问题的情况下它看起来像这样:

    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);
    

    我以这种方式限制了一些导航集合,并且效果非常好。