我有一个应用程序将对象列表序列化为json,然后通过套接字连接将其发送给客户端。
在客户端,我使用JsonConvert.PopulateObject()用新接收的json数据填充现有的对象列表。但是,如果存在任何重复项,则会不断将对象附加到列表中,而不是重复使用列表中的现有对象。
以下是我正在序列化/反序列化的课程:
public class Process : INotifyPropertyChanged
{
private int _id;
private string _name;
public int ID
{
get { return _id; }
set
{
if (value != _id)
{
_id = value;
NotifyPropertyChanged("ID");
}
}
}
public string Name
{
get { return _name; }
set
{
if (value != _name)
{
_name = value;
NotifyPropertyChanged("Name");
}
}
}
public Process() { }
public Process(int id, string name)
{
ID = id;
Name = name;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
这是我使用的PopulateObject代码:
JsonSerializerSettings settings = new JsonSerializerSettings() { PreserveReferencesHandling = PreserveReferencesHandling.Objects, ObjectCreationHandling = ObjectCreationHandling.Auto };
ObservableCollection<Process> Processes = new ObservableCollection<Process>();
JsonConvert.PopulateObject(response, Processes, settings);
尽管属性值完全相同,但json.net似乎并不知道对象是重复的引用。我已经在我的类上尝试了多个JsonObject属性组合(IsReference = true,Id =&#34; ID&#34;)等等。我似乎无法让json识别两个对象是否相同,如果他们的ID财产匹配。
答案 0 :(得分:0)
您是否已尝试覆盖已加强化对象的Equals()函数
public override bool Equals(Process p)
{
// If parameter is null return false:
if ((object)p == null)
{
return false;
}
// Return true if the fields match:
return (ID == p.ID);
}
答案 1 :(得分:0)
这不是PreserveReferencesHandling
的作用。它用于避免序列化重复对象,有效缩短json结果。例如:
List<NameValuePair> nvpList = new List<NameValuePair>();
NameValuePair z = new NameValuePair(Name="Ziggy", Value= 42);
nvpList.Add(z);
nvpList.Add(new NameValuePair("Zoey", 3));
nvpList.Add(z);
JsonSerializerSettings settings = new JsonSerializerSettings() {
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
};
string json = JsonConvert.SerializeObject(nvpList, Formatting.Indented,
settings);
我的List
有2个Ziggy对象,但生成的json是:
[
{
"$id": "1",
"Name": "Ziggy",
"Value": 42
},
{
"$id": "2",
"Name": "Zoey",
"Value": 3
},
{
"$ref": "1"
}
]
它分配内部$Id
,然后引用重复对象的内容。这仅适用于对象引用相同的情况。如果创建并添加了2个Ziggy对象 - 即使具有相同的值 - json将反映并重复它们。
为防止反序列化时列表中出现重复,您必须使用映射器或等效代码:
List<NameValuePair> tmp = JsonConvert.DeserializeObject<List<NameValuePair>>(json);
foreach (NameValuePair nvp in tmp)
{
if (nvpList.Where(w => w.Value == nvp.Value).FirstOrDefault() == null)
{
nvpList.Add(nvp);
}
}
这只会添加主列表中尚不存在Value / Id的那些,添加检测欺骗所需的任何逻辑。