JSON Newtonsoft C#序列化/反序列化对象列表的良好实践

时间:2016-06-05 14:25:14

标签: c# json asp.net-mvc list json.net

我在这里就这个问题引用了其他帖子

Serializing a list of Object using Json.NET

Serializing a list to JSON

Merge two objects during serialization using json.net?

一切都非常有用。确实,我可以在一个json两个列表中序列化,但我不能反序列化它。

我正在使用Json Newtonsoft,C#,MVC5,framework 4.5。这是场景:

C#CODE

public class User
{
    public int id { get; set; }
    public string name { get; set; }
}

public class Request
{
    public int id { get; set; }
    public int idUSer{ get; set; } 
}

List<User> UserList = new List<User>();          
List<Request> RequestList = new List<Request>();
string json=  JsonConvert.SerializeObject(new { UserList, RequestList });

JSON RESULT

{
"UserList":[
  {
     "id":1,
     "name":"User 1"
  },
  {
     "id":2,
     "name":"User 2"
  },
  {
     "id":3,
     "name":"User 3"
  }
 ],
"RequestList":[
  {
     "id":1,
     "idUSer":1
  },
  {
     "id":2,
     "idUSer":1
  },
  {
     "id":3,
     "idUSer":1
  },
  {
     "id":4,
     "idUSer":2
  }
  ]
  }

C#DESERIALIZE

我不知道如何配置Json.Deserialize&lt;的设置。 ?,设置&gt;(json)用于指示正​​在反序列化的对象类型。

改变方法

这样,改变方法,我创建了一个新类“Cover”,以便将列表放在一起并序列化一个对象

 public class Cover
 {
    private List<User> user = new List<User>();
    private List<Request> request = new List<Request>();

    public List<User> User 
    { 
        get { return user;}
        set { User = value;}        
    }      

    public List<Request> Request
    {
        get {return request;}
        set {Request = value;}
    }
  }

SERIALIZE

string json = JsonConvert.SerializeObject(cover);

JSON json结果是一样的。

DESERIALIZE

 Cover  result = JsonConvert.DeserializeObject<Cover>(json, new 
 JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });

工作正常。我的情况得到了解决,但我对概念产生怀疑,在我看来,有些事情并不清楚:

我的问题是:

第一个方法:

你认为有一种方法可以用不同的对象列表反序列化json吗?这不是一个好习惯吗?

第二个方法:为什么jsons等于第一种情况?

2 个答案:

答案 0 :(得分:2)

在JSON.NET中,您需要通过将其名称作为类型参数提供给DeserializeObject来指定您要反序列化的类型。 但是,在这一行:

string json=  JsonConvert.SerializeObject(new { UserList, RequestList });

您创建匿名对象,然后将其序列化 - new { UserList, RequestList }。所以有捕获 - 你不能使用匿名类型作为类型参数。 为了处理这种情况,JSON.NET提供了DeserializeAnonymousType<>。它并不要求你提供类型参数;实际上你不能反序列化匿名类型。相反,它是从传递给方法的第二个参数的类型推断出来的。所以你只需要创建一个没有数据的虚拟匿名对象,并将其传递给这个方法。

// jsonData contains previously serialized List<User> and List<Request>
void DeserializeUserAndRequest(string jsonData) 
{
    var deserializedLists = new { 
        UserList = new List<User>(), 
        RequestList = new List<Request>() 
    };
    deserializedLists = JsonConvert.DeserializeAnonymousType(jsonData, deserializedLists);

    // Do your stuff here by accessing 
    //  deserializedLists.UserList and deserializedLists.RequestLists
}

当然这一切都运行正常,但这种方法表明您已经知道序列化数据的结构。如果此结构与您匿名类型初始化的结构不匹配,则您将在DeserializeAnonymousType方法之后得不到任何内容。这不仅适用于匿名类型的属性类型,也适用于它们的名称。

答案 1 :(得分:2)

关于你的第一个问题:

我会考虑Cover类的选项&#39;最佳实践&#39;因为您使用相同的模型进行序列化和反序列化,所以由Json.NET来决定如何进行(反)序列化魔术。

如果由于某种原因你不想使用这种方法,还有另外两种选择:

关于第二个问题 - 您确定生成的JSON与两种方法完全相同吗? (您可以使用www.diffchecker .com等工具进行验证)

使用您的第二种方法,顶级名称应该是不同的 - 它应该是&#39;用户&#39;而不是&#39; UserList&#39;和&#39;请求&#39;而不是&#39; RequestList&#39;