【发布时间】:2019-02-15 13:51:56
【问题描述】:
我想使用 Json.NET 仅序列化对象的某些属性。
我正在使用类似Json.net serialize only certain properties 帖子中描述的解决方案。
我的问题是我每次都想选择不同的属性,并且出于性能原因对CreateContract(又调用CreateProperties)的调用被缓存(源代码:https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs)。
有没有办法只序列化我想要的属性,每次都指定不同的属性,可能不需要重写整个DefaultContractResolver 类?
这是一个显示这个问题的程序:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
class Person {
public int Id;
public string FirstName;
public string LastName;
}
public class SelectedPropertiesContractResolver<T> : CamelCasePropertyNamesContractResolver {
HashSet<string> _selectedProperties;
public SelectedPropertiesContractResolver(IEnumerable<string> selectedProperties) {
_selectedProperties = selectedProperties.ToHashSet();
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) {
if (type == typeof(T)) {
return base.CreateProperties(type, memberSerialization)
.Where(p => _selectedProperties.Contains(p.PropertyName, StringComparer.OrdinalIgnoreCase)).ToList();
}
return base.CreateProperties(type, memberSerialization);
}
}
class Program {
static void Main(string[] args) {
var person = new Person { Id = 1, FirstName = "John", LastName = "Doe" };
var serializer1 = new JsonSerializer {
ContractResolver = new SelectedPropertiesContractResolver<Person>(new[] { "Id", "FirstName" })
};
// This will contain only Id and FirstName, as expected
string json1 = JObject.FromObject(person, serializer1).ToString();
var serializer2 = new JsonSerializer {
ContractResolver = new SelectedPropertiesContractResolver<Person>(new[] { "LastName" })
};
// Since calls to CreateProperties are cached, this will contain Id and FirstName as well, instead of LastName.
string json2 = JObject.FromObject(person, serializer2).ToString();
}
}
【问题讨论】:
-
正如@MurrayFoxcroft 所说:首先要尝试的是
ShouldSerialize*(“条件序列化”)模式,即Json.NET supports -
谢谢,条件序列化似乎是可行的方法。