在运行时动态切换适用的DataContract?

时间:2013-05-09 19:41:01

标签: json serialization deserialization servicestack datacontract

我可以动态关闭和打开数据合约属性吗?基本上,我想要两个数据合同,一个在第三方和我的应用之间,一个在我的应用和我的客户之间 - 无需管理两个DTO类。例如,考虑MyDTO:

[DataContract]
public class MyDTO
{
    [DataMember(Name = "Lame/3rdParty/Inbound/Key")]
    public string MyCoolOutboundKey { get; set; }
}

我想用ServiceStack.Text反序列化DTO:

MyDTO dto = "{\"Lame/3rdParty/Inbound/Key\":\"CoolValue\"}".FromJson<MyDTO>();

但是,我想序列化它以便这个断言是真的:

Assert.AreEqual("{\"MyCoolOutboundKey\":\"CoolValue\"}",dto.ToJson());

有问题的实际对象有超过一百个属性,所以我希望避免为了允许出站序列化而创建第二个类。

2 个答案:

答案 0 :(得分:2)

所以,你的方法没有任何问题,但我认为你低估了JsonObject的力量,它有点像LINQ to JSON。

我用它来从谷歌地图获取地理数据并将其映射到一个漂亮的小DTO:

var jsonObj = jsonFromGoogleMaps.FromJson<JsonObject>();

return (
    from x in jsonObject.Get<JsonArrayObjects>("results")
    let geo = x.Get("geometry")
    let loc = geo.Get("location")
    return new Coords
    {
        Lat = x.Get<decimal>("lat"),
        Lng = x.Get<decimal>("lng"),
    }
).FirstOrDefault();

答案 1 :(得分:1)

好的 - you cannot change attributes at runtime已经很明确了。

在整个问题上创建一个终点运算的替代方案是预处理传入的json,根据映射替换密钥,即:

Dictionary<String,String> map = new Dictionary<String,String>();
map.Add("Lame/3rdParty/Inbound/Key","MyCoolOutboundKey");

JsonObject result = new JsonObject();
JsonObject obj = jsonObject.Parse("{\"Lame/3rdParty/Inbound/Key\":\"CoolValue\"}");

foreach (var entry in obj)
{
    entry.Key = map[entry.Key];
    result[entry.Key] = entry.Value;
}

Assert.AreEqual("{\"MyCoolOutboundKey\":\"CoolValue\"}",result.ToJson());

这样我唯一需要的数据合同就是我的应用和我应用的客户之间的合约。