序列化时,子元素的Newtonsoft内联格式

是否可以使用newtonsoft json.net创建一个内联序列化子元素(Formatting.None)的属性?

我有一个非常庞大的数据集,我想保持它的可重复性。 一些子元素不是很重要,可以内联写入。

{ "name": "xxx", "desc": "xxx", "subelem": [ {"val1": 1, "val2": 2, ...}, //inline, {"val1": 1, "val2": 2, ...}, ... ] "subelem2": { "val1": 1, "val2": 2, ... } } 

我想强制我的模型的一些子对象的内联序列化。 在这种情况下,“subelem”项目将内联写入。 谢谢

在类上添加转换器作为JsonConverterAttribute是比较棘手的,因为最简单的实现会在转换器调用自身时导致无限递归。 因此,必须以线程安全的方式禁用转换器以进行递归调用,如下所示:

 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(true, () => CannotWrite, val => CannotWrite = val)) using (new PushValue(Formatting.None, () => writer.Formatting, val => writer.Formatting = val)) { serializer.Serialize(writer, value); } } } public struct PushValue : IDisposable { Action setValue; T oldValue; public PushValue(T value, Func getValue, Action 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 } 

然后将它应用于类(或属性),如下所示:

 [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)); } } 

上面的Test()方法的输出是:

 { "AValue": "A Value", "NestedClass":{"Values":["one","two","three"]}, "ZValue": "Z Value" }