【问题标题】:Stripping fields from entities when returning entities from a WCF service从 WCF 服务返回实体时从实体中剥离字段
【发布时间】:2013-01-05 13:24:29
【问题描述】:

我有一个多层系统,其中所有业务逻辑都可以通过 WCF 服务使用。

现在考虑以下场景:

  1. 用户打开我的 Web 应用程序 (ASP.NET MVC 4) 并从 WCF 服务请求一些实体
  2. WCF 服务从数据库中读取实体(使用 NHibernate)
  3. 实体通过安全层,我们发现用户不应该看到该实体的某些特定字段
  4. 表示层(没关系,它是什么 - Web 应用程序、移动应用程序)通常不应该知道用户的安全权限。表示层只获取它从服务接收到的每个字段并呈现它。

如何从服务上的实体中去除不必要的信息,并使我的表示层不知道服务不想返回的那些实体字段?实现这一目标的最佳做法是什么?

我想,我应该使用 DTO(数据传输对象),但显然我不能严格定义它们,因为在安全层(或其他一些字段过滤系统)启动之前,我不知道哪个用户可以访问每个字段。

【问题讨论】:

    标签: c# wcf serialization dynamic data-transfer-objects


    【解决方案1】:

    虽然我不能说这是“最佳实践”,但至少这是 Rockford Lhotka 在Expert C# 2008 Business Objects 中采用的一种方法。

    您可以让所有域实体最终都派生自某个基类。该基类可能有这样的方法:

    public virtual bool CanReadProperty(string propertyName) { ... }
    

    在允许用户查看(或设置)之前,每个属性都可以调用该方法。为了获得更好的性能,该基类可以缓存授权角色,因此检查不是一项昂贵的操作。当然,现在我们有了表达式树,CanReadProperty() 可以接受一个表达式,使其成为强类型。

    属性示例如下所示:

    public string Name
    {
        get
        {
            if (!CanReadProperty("Name")) { return string.Empty; } // or return null, whatever...
            return _name;
        }
    }
    

    这种方法的好处是您不需要很多不同的 DTO 来处理这些属性的查看可能发生变化的各种场景。

    【讨论】:

    • 好的,这解决了服务器上的问题。为了能够在 WCF 客户端处理它,我需要以某种方式传递身份验证规则,以便客户端上的实体也知道哪些字段不可见。当然,这意味着 WCF 仍然会返回“不可见”字段,但我想这是可以接受的。我想避免创建我自己的序列化程序,它将我的实体转换为一些动态属性包 - 这真的很复杂。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多