5

我们编写了一个 Web 服务,它使用一个简单的实体转换器将 DTO 的值映射回“真实的”服务器端业务对象。作为本次练习的一部分。我们遇到了显式设置空值和未设置值的客户端之间的“有趣”区别。

问题本质上是,如果客户端没有显式设置值,我们想在实际业务对象上设置默认值,但是使用标准的可空类型无法判断客户端是否明确表示“将其设置为 null ” 。或者只是不设置它。

这里的解决方案显然是某种“标志”。

在业务对象中,我们可以使用在属性设置器中设置的私有“IsDirty”标志在内部跟踪字段的状态,但是 DTO 只真正指定了一个接口,因此这意味着将这些数据公开给公众。这留下了许多实现选项。语言是 C#(所以是静态类型的)所以...

  1. 我们可以在每个属性上公开一个“IsSet”标志吗?
  2. 我们可以将每个属性公开为具有 .Value 和 .IsSet 属性的类吗?等等等等

将如何选择在数据合约上公开这些“标志”?您在这里认为最佳实践是什么?

对此的任何意见将不胜感激。

4

4 回答 4

3

为每个属性值使用一个类将比必须为每个属性声明一个布尔值更具可扩展性。它还使您能够选择哪些属性可以留空和/或设置为空。

于 2009-05-11T07:53:33.030 回答
3

您可以编写一个用数据包装标志的类:

public class DtoData<T> 
{
  T data;
  bool IsSet { get; private set; }
  T Data 
  { 
    get { return data; }
    set { data = value; IsSet = true; } 
  }
}


public class XyzDto 
{
  // only private setters, initialize in constructor
  DtoData<int?> SomeInt { get; private set; }
  DtoData<string> SomeString { get; private set; }
}

这有一些缺点。例如,您的所有数据都包装在引用类型中,因此对 DtoData 的引用仍可能为空,您需要在构造函数中创建它们。并且很难使值只能在内部或受保护的情况下访问。


就个人而言,我会尽量避免这个问题。为什么“未定义”实际上应该存在?您是在发送差异、不完整的 Dto,还是来自哪里?过滤器可能会出现此问题,如果您将字段过滤为 null 或根本不过滤,则需要有所不同。但是对于这种情况,无论如何你都需要一个特殊的“字段过滤器”类。

于 2009-05-11T07:56:46.443 回答
1

一般来说,您在这里谈论的是一个默认值,它不同于用户可以设置的任何值。因此,只需指定即可;将默认值设置为不在用户可以设置的允许值范围内的值。这样,如果该值是默认值,则您知道它尚未设置;如果值不是那个值,你就知道用户已经修改了它。仅仅因为用户可设置的值之一是 null 似乎会让你失望;只需将其视为一组用户可设置值之一;使变量的整个范围成为一个稍大的集合,并具有一个额外的默认值。那应该可以解决您的问题。

于 2009-05-11T21:50:25.373 回答
0

我以前遇到过这个确切的问题。您可以通过在 DTO 的构造中引入一些默认值来解决此问题,但这并不理想。我在这里写了更详细的博客,它可能会帮助人们进一步理解这个问题。

于 2009-05-11T08:08:01.853 回答