我正在从一组类中使用Newtonsoft.Json创建一个JSON文件.创建的文件非常大,所以我JsonProperty为属性创建了s来减小大小,JsonIgnore并为某些数据类型添加和自定义格式.
结果是从24MB减少到1MB,这很好; 但是,我希望选择在运行时生成完整版本或简化属性版本.
无论如何,我可以让序列化器可选地使用属性吗?
Bri*_*ers 39
是的,这可以使用自定义完成ContractResolver.
你没有显示任何代码,所以我只是举个例子.假设我有一个Foo如下所示的课程.我想要序列化输出中的Id和Name属性,但我绝对不感兴趣AlternateName和Color.我用那些标记了[JsonIgnore].我想要出现描述,但有时这可能会变得很长,所以我使用自定义JsonConverter来限制它的长度.我还想使用更短的属性名称来描述,所以我用它标记了它[JsonProperty("Desc")].
class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public string AlternateName { get; set; }
[JsonProperty("Desc")]
[JsonConverter(typeof(StringTruncatingConverter))]
public string Description { get; set; }
[JsonIgnore]
public string Color { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我序列化上面的一个实例时......
Foo foo = new Foo
{
Id = 1,
Name = "Thing 1",
AlternateName = "The First Thing",
Description = "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.",
Color = "Yellow"
};
string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
Run Code Online (Sandbox Code Playgroud)
...我得到这个输出:
{
"Id": 1,
"Name": "Thing 1",
"Desc": "This is some lengthy text describing Thing 1 "
}
Run Code Online (Sandbox Code Playgroud)
现在,让我们说我有时想要获得完整的JSON输出,忽略我的自定义.我可以使用自定义ContractResolver以编程方式"取消应用"类中的属性.这是解析器的代码:
class IgnoreJsonAttributesResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
foreach (var prop in props)
{
prop.Ignored = false; // Ignore [JsonIgnore]
prop.Converter = null; // Ignore [JsonConverter]
prop.PropertyName = prop.UnderlyingName; // restore original property name
}
return props;
}
}
Run Code Online (Sandbox Code Playgroud)
要使用解析器,我将其添加到JsonSerializerSettings并将设置传递给序列化器,如下所示:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new IgnoreJsonAttributesResolver();
settings.Formatting = Formatting.Indented;
string json = JsonConvert.SerializeObject(foo, settings);
Run Code Online (Sandbox Code Playgroud)
输出现在包括被忽略的属性,并且描述不再被截断:
{
"Id": 1,
"Name": "Thing 1",
"AlternateName": "The First Thing",
"Description": "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.",
"Color": "Yellow"
}
Run Code Online (Sandbox Code Playgroud)
这里有完整的演示:https://dotnetfiddle.net/WZpeWt