是啊,这可能会非常棘手,因为你想在构造函数中的版本号,以便每个呼叫在同一构造函数将使用相同的时间分配了含蓄的版本时,你反序列化到新的当你第一次添加Version
信息DTO。
不幸的是,原始DTO中没有版本,因此它不会被序列化到网络上,因此它不会覆盖隐式分配的版本字段。
要解决此问题(并在构造函数中保留隐式赋值的版本号),您需要有效地重置在反序列化中使用的版本。
您可以通过覆盖在App_Start的JsConfig.ModelFactory
用JSON/JSV串行做到这一点(即在你的AppConfig),它允许您控制在反序列化使用的每种类型POCO创建的实例。
在这种情况下,我们要重置,有一个版本回到0
这样的DTO没有版本号的任何DTO分配0
DTO的同时,用版本号将覆盖它:
JsConfig.ModelFactory = type => {
if (typeof(IHasVersion).IsAssignableFrom(type))
{
return() => {
var obj = (IHasVersion)type.CreateInstance();
obj.Version = 0;
return obj;
};
}
return() => type.CreateInstance();
};
我使用明确的IHasVersion
界面为简单起见,但您也可以轻松地使用反射来检测和重新分配包含版本号的类型。
下面是一个原始的DTO的例子没有版本属性反序列化到一个DTO与隐含分配版本号:
public class Dto
{
public string Name { get; set; }
}
public interface IHasVersion
{
int Version { get; set; }
}
public class DtoV1 : IHasVersion
{
public int Version { get; set; }
public string Name { get; set; }
public DtoV1()
{
Version = 1;
}
}
现在,当你反序列化原DTO转化成其保留为0的新DtoV1
:
var dto = new Dto { Name = "Foo" };
var fromDto = dto.ToJson().FromJson<DtoV1>();
fromDto.Version // 0
fromDto.Name // Foo
如果你使用新的DTO它填充的版本号:
var dto1 = new DtoV1 { Name = "Foo 1" };
var fromDto1 = dto1.ToJson().FromJson<DtoV1>();
fromDto.Version // 1
fromDto.Name // Foo 1
wsrl
令人难以置信的解决方案。感谢mythz – BoKDamgaard