我们编写了一个Web服务,它使用一个简单的实体转换器将DTO的值映射回“真正的”服务器端业务对象。作为这个练习的一部分。我们在明确设置空值和未设置值的客户端之间遇到了“有趣”的区别。
问题本质上是我们想要在真实业务对象上设置默认值,如果客户端没有明确设置值,但是使用标准的可空类型则无法判断是否存在客户明确表示“将此设置为空”或者只是不设置它。
这里的解决方案显然是某种“旗帜”。
在业务对象中,我们可以使用属性设置器中设置的私有“IsDirty”标志在内部跟踪字段的状态,但是DTO只是真正指定了接口,因此这意味着将此数据公开给公众。这留下了许多实现选项。语言是C#(如此静态类型)所以......
你如何选择在数据合约上公开这些“标志”? 你认为这是什么最好的做法?
对此的任何意见将不胜感激。
答案 0 :(得分:3)
为每个属性值使用一个类将更具可伸缩性,必须为每个属性声明一个bool。它还可以让您选择哪些属性可以保留为空和/或设置为空。
答案 1 :(得分: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的引用仍然可以为null,您需要在构造函数中创建它们。并且很难使值只能在内部访问或受到保护。
就个人而言,我会尽量避免这个问题。为什么“未定义”确实存在?你是在发送差异,不完整的Dtos,或者它来自哪里?此问题可能来自过滤器,如果您将字段过滤为null或者根本不过滤它,则需要区别。但是对于这种情况,无论如何你都需要一个特殊的“场过滤器”类。
答案 2 :(得分:1)
一般来说,你在这里谈论的是一个默认值,它与用户可以设置的任何值都不同。所以只需指定;将默认值设置为不在用户可以设置的允许值范围内的值。这样,如果该值是默认值,则表示尚未设置;如果值不是那个,你知道用户已经修改了它。仅仅因为其中一个用户可设置的值为null似乎就是在抛弃你;只是将它视为用户可设置值集之一;将变量的整个范围设置为略大的一组,并带有一个额外的默认值。这应该可以解决你的问题。
答案 3 :(得分:0)
之前我遇到过这个问题。您可以通过在构建DTO时引入一些默认值来解决这个问题,但这并不理想。我已经更详细地发布了博客here,它可能有助于有人进一步了解这个问题。