2012-11-02 23 views
3

我读过这篇文章的@mythz https://stackoverflow.com/a/12413091/1095655,但我的声望不够高置评版本在ServiceStack - 再次

我有一个问题是决策工作。如果使用版本1 DTO获取请求,则版本不存在于传输的数据中,因为版本1 DTO没有版本属性。当ServiceStack对请求进行反序列化时,它会创建一个DTO对象(版本3),并将版本设置为2,并且由于未从传输的数据收到版本,所以版本未按预期覆盖为0。 正如我所看到的,您需要从DTO开始实施版本,否则它将无法正常工作。

希望我错了,有人可以澄清我失踪了什么?这可以解决,因为我有一个DTO在生产没有版本实现?

回答

3

是啊,这可能会非常棘手,因为你想在构造函数中的版本号,以便每个呼叫在同一构造函数将使用相同的时间分配了含蓄的版本时,你反序列化到新的当你第一次添加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
+0

令人难以置信的解决方案。感谢mythz – BoKDamgaard

相关问题