我刚开始使用Newtonsoft.Json(Json.net).在我的第一个简单测试中,我在反序列化通用列表时遇到了问题.在下面的代码示例中,我序列化了一个对象,其中包含三种类型的简单整数列表(属性,成员var和数组).
生成的json看起来很好(列表转换为json数组).但是,当我将json反序列化为相同类型的新对象时,所有列表项都是重复的,期望数组.我已经通过第二次序列化来说明了这一点.
从搜索周围,我已经读到可能有一个"私人"支持字段到解串器也填充的列表.
所以我的问题是:在下列情况下是否有(最好是简单的)避免重复项目的方法?
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace JsonSerializeExample
{
public class Program
{
static void Main()
{
var data = new SomeData();
var json = JsonConvert.SerializeObject(data);
Console.WriteLine("First : {0}", json);
var data2 = JsonConvert.DeserializeObject<SomeData>(json);
var json2 = JsonConvert.SerializeObject(data2);
Console.WriteLine("Second: {0}", json2);
}
}
public class SomeData
{
public string SimpleField;
public int[] IntArray;
public IList<int> IntListProperty { get; set; }
public IList<int> IntListMember;
public SomeData()
{
SimpleField = "Some data";
IntArray = new[] { 7, 8, 9 };
IntListProperty = new List<int> { 1, 2, 3 };
IntListMember = new List<int> { 4, 5, 6 };
}
}
}
Run Code Online (Sandbox Code Playgroud)
First : {"SimpleField":"Some data","IntArray":[7,8,9],"IntListMember":[4,5,6],"IntListProperty":[1,2,3]}
Second: {"SimpleField":"Some data","IntArray":[7,8,9],"IntListMember":[4,5,6,4,5,6],"IntListProperty":[1,2,3,1,2,3]}
Run Code Online (Sandbox Code Playgroud)
这里可能存在一些重叠,Json.Net复制了私有列表项.但是,我认为我的问题更简单,我仍然没有想到它.
Mar*_*ell 23
那是因为您在构造函数中添加项目.处理列表时反序列化器中的常用方法基本上是:
Add
)附加到列表中这是因为大多数列表成员没有setter,即
public List<Foo> Items {get {...}} // <=== no set
Run Code Online (Sandbox Code Playgroud)
与数组形成对比,数组必须有一个有用的setter; 因此,方法通常是:
Add
)附加到临时列表ToArray
),并通过setter进行分配一些序列化程序为您提供了控制此行为的选项(其他人没有); 并且一些序列化程序使您能够完全绕过构造函数(其他人没有).
小智 10
我很确定这篇文章不再相关,但为了将来参考,这里有一个可行的解决方案。只需要指定ObjectCreationHandling
设置为Replace
,即始终创建新对象而不是Auto
(这是默认设置)即重用现有对象,在需要时创建新对象。
var data = new SomeData();
var json = JsonConvert.SerializeObject(data);
Console.WriteLine("First : {0}", json);
var data2 = JsonConvert.DeserializeObject<SomeData>(json, new JsonSerializerSettings() { ObjectCreationHandling = ObjectCreationHandling.Replace });
var json2 = JsonConvert.SerializeObject(data2);
Console.WriteLine("Second: {0}", json2);
Run Code Online (Sandbox Code Playgroud)
我遇到了一个不同根本原因的类似问题.我正在序列化和反序列化一个看起来像这样的类:
public class Appointment
{
public List<AppointmentRevision> Revisions { get; set; }
public AppointmentRevision CurrentRevision
{
get { return Revision.LastOrDefault(); }
}
public Appointment()
{
Revisions = new List<AppointmentRevision>();
}
}
public class AppointmentRevision
{
public List<Attendee> Attendees { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我序列化时,CurrentRevision也被序列化了.我不确定如何,但是当它反序列化时,它正确地保留了AppointmentRevision的单个实例,但在Attendees列表中创建了重复项.解决方案是在CurrentRevision属性上使用JsonIgnore属性.
public class Appointment
{
public List<AppointmentRevision> Revisions { get; set; }
[JsonIgnore]
public AppointmentRevision CurrentRevision
{
get { return Revision.LastOrDefault(); }
}
public Appointment()
{
Revisions = new List<AppointmentRevision>();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6201 次 |
最近记录: |