是啊,這可能會非常棘手,因爲你想在構造函數中的版本號,以便每個呼叫在同一構造函數將使用相同的時間分配了含蓄的版本時,你反序列化到新的當你第一次添加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