首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >版本依赖的Json反序列化

版本依赖的Json反序列化
EN

Stack Overflow用户
提问于 2016-03-25 10:28:18
回答 5查看 4.7K关注 0票数 7

我正在寻找一种从Json进行反序列化的方法,以便使用Json本身中的数据进行版本依赖。我的目标是使用ServiceStack.Text.JsonDeserializer,但可以切换到另一个库。

例如,我想在JSON中为v1.0定义一个数据如下:

代码语言:javascript
复制
{
    version: "1.0"
    condition: "A < B"
}

然后,数据的下一个版本(例如2.0)是:

代码语言:javascript
复制
{
    version: "2.0"
    condition: ["A < B", "B = C", "B < 1"]
}

最后,我希望能够验证数据的版本,以了解如何正确地反序列化JSON。

更新:

在已知的产品中,似乎没有对版本依赖的JSON (反)序列化的任何隐式支持。

正确的解决方案似乎是将任务拆分为(反)只序列化版本部分,然后对正确的类型使用隐式(反)序列化。

感谢每一个分享关于这个问题的知识和想法的人。

EN

回答 5

Stack Overflow用户

发布于 2016-03-25 11:15:18

您可以这样做:

  • 为要反序列化的数据对象创建一个基类,该类包含version字段,而不包含其他任何内容。
  • 使您的不同版本的数据类成为此基类的派生类。
  • 当您反序列化数据对象时,首先,将其反序列化为基类的一个实例--因此现在您有了一个包含版本号的POCO对象。您可以使用它来决定应该使用哪些派生数据类来反序列化数据(在最简单的情况下,您可以执行一个开关/用例并单独处理每个版本)。

一个示例(使用System.Web.Script.Serialization.JavaScriptSerializer):

代码语言:javascript
复制
class BaseClass 
{
    public int version { get; set; }
}

class FirstVersion: BaseClass 
{
    public string condition { get; set; }
}

class SecondVersion: BaseClass
{
    public IEnumerable<string> condition { get; set; }
}

public void Deserialize (string jsonString)
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    BaseClass myData = serializer.Deserialize<BaseClass>(jsonString);

    switch (myData.version) 
    {
        case 1:
            FirstVersion firstVersion = serializer.Deserialize<FirstVersion>(jsonString);
            // ...
            break;
        case 2:
            SecondVersion secondVersion = serializer.Deserialize<SecondVersion>(jsonString);
            // ...
            break;
    }
}

正如您所看到的,这段代码两次反序列化数据--如果您使用大型数据结构,这可能是一个问题。如果您想不惜一切代价避免这种情况,您要么放弃静态类型,要么修改应用程序的数据模型。

下面是使用dynamic的样子

代码语言:javascript
复制
public void Deserialize (string jsonString)
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    dynamic myData = serializer.Deserialize<object>(jsonString);

    if (myData ["version"] == 1) {
        ...
    }
}

还有一个选项可以编写您自己的自定义JavaScriptConverter。这是一个更多的工作,但我很肯定,你可以实现你想要的,它将看起来更好。

要考虑的另一个建议是永远不要从JSON结构中删除属性。如果您需要修改一个属性,请保留旧的属性并添加一个新的属性--这样,旧代码就可以从更新的代码中读取数据。当然,如果您经常修改数据结构,这可能很快就会失控。

在Java中,您可以使用谷歌的GSON库,因为它有一个版本控制内置支持。我还没有研究过它,但它是开源,如果它对您非常重要,我想您可以将实现移植到另一种语言。

票数 7
EN

Stack Overflow用户

发布于 2016-03-25 12:37:26

我建议您使用json.net,它允许您添加可以用于版本控制的自定义类型转换。

问题不是序列化,因为它将始终使用当前架构。问题是当客户端使用接收对象的服务器的不同类型版本时。

您需要做的是在类型转换器中以编程方式检查版本,并自己转换值(在本例中,将字符串转换为数组)。

文档:http://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm

票数 1
EN

Stack Overflow用户

发布于 2016-03-25 10:41:13

您可能需要使用NewtonSoft.Json NuGET软件包

这是.NET社区中的一种标准。它也常被称为Json.NET

您可以这样使用它(来自官方网站的示例):

代码语言:javascript
复制
Product product = new Product();

product.Name = "Apple";
product.ExpiryDate = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string output = JsonConvert.SerializeObject(product);
//{
//  "Name": "Apple",
//  "ExpiryDate": "2008-12-28T00:00:00",
//  "Price": 3.99,
//  "Sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}

Product deserializedProduct = JsonConvert.DeserializeObject<Product>(output);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36218196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档