C# 序列化时子元素的Newtonsoft内联格式
是否可以创建一个属性,用newtonsoft json.net内联序列化某些子元素(Formatting.None) 我有一个非常庞大的数据集,我想保持它的可读性。 有些子元素不是很重要,可以内联写入C# 序列化时子元素的Newtonsoft内联格式,c#,json.net,C#,Json.net,是否可以创建一个属性,用newtonsoft json.net内联序列化某些子元素(Formatting.None) 我有一个非常庞大的数据集,我想保持它的可读性。 有些子元素不是很重要,可以内联写入 { "name": "xxx", "desc": "xxx", "subelem": [ {"val1": 1, "val2": 2, ...}, //inline, {"val1": 1, "val2": 2, ...},
{
"name": "xxx",
"desc": "xxx",
"subelem": [
{"val1": 1, "val2": 2, ...}, //inline,
{"val1": 1, "val2": 2, ...},
...
]
"subelem2": {
"val1": 1,
"val2": 2,
...
}
}
我想强制对模型的一些子对象进行内联序列化。
在这种情况下,“子元素”项将内联写入。
谢谢,在类上添加转换器是一件棘手的事情,因为最简单的实现会在转换器调用自身时导致无限递归。因此,有必要以线程安全的方式禁用用于递归调用的转换器,如下所示:
public class NoFormattingConverter : JsonConverter
{
[ThreadStatic]
static bool cannotWrite;
// Disables the converter in a thread-safe manner.
bool CannotWrite { get { return cannotWrite; } set { cannotWrite = value; } }
public override bool CanWrite { get { return !CannotWrite; } }
public override bool CanRead { get { return false; } }
public override bool CanConvert(Type objectType)
{
throw new NotImplementedException(); // Should be applied as a property rather than included in the JsonSerializerSettings.Converters list.
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
using (new PushValue<bool>(true, () => CannotWrite, val => CannotWrite = val))
using (new PushValue<Formatting>(Formatting.None, () => writer.Formatting, val => writer.Formatting = val))
{
serializer.Serialize(writer, value);
}
}
}
public struct PushValue<T> : IDisposable
{
Action<T> setValue;
T oldValue;
public PushValue(T value, Func<T> getValue, Action<T> setValue)
{
if (getValue == null || setValue == null)
throw new ArgumentNullException();
this.setValue = setValue;
this.oldValue = getValue();
setValue(value);
}
#region IDisposable Members
// By using a disposable struct we avoid the overhead of allocating and freeing an instance of a finalizable class.
public void Dispose()
{
if (setValue != null)
setValue(oldValue);
}
#endregion
}
上述Test()
方法的输出为:
我和前段时间问了同样的问题,得到了一个很好的答案:扩展链接答案,如果你想缩进完全基于深度,你可以从中得到(虽然它是受保护的,所以你可能需要对
JsonTextWriter
进行子类化,并创建一个公共方法)。不幸的是,在我目前的情况下,它不是基于深度的,但我有另一个案件,将符合您的答案,谢谢我会尝试与自定义转换器。您知道是否可以使用带有自定义属性的自定义转换器吗?我将有许多不同的对象需要它,如果我能为每个不同的对象创建一个自定义属性而不是一个转换器,那就太好了。无论如何,我可以使用你的解决方案。这正是我需要的。非常感谢你!我试着做那样的东西,但我确实遇到了你提到的问题。
[JsonConverter(typeof(NoFormattingConverter))]
public class NestedClass
{
public string[] Values { get; set; }
}
public class TestClass
{
public string AValue { get; set; }
public NestedClass NestedClass { get; set; }
public string ZValue { get; set; }
public static void Test()
{
var test = new TestClass { AValue = "A Value", NestedClass = new NestedClass { Values = new[] { "one", "two", "three" } }, ZValue = "Z Value" };
Debug.WriteLine(JsonConvert.SerializeObject(test, Formatting.Indented));
}
}
{
"AValue": "A Value",
"NestedClass":{"Values":["one","two","three"]},
"ZValue": "Z Value"
}