序列化 – 如何使用Json.NET序列化C#中的“类似联合”字段

我正在尝试生成一个将在Dojo javascript框架中使用的 JSON文件,并希望返回一个位置属性以在 dojo.place()调用中使用. position参数可以是数字或字符串.

使用StructLayout似乎不能正常工作,因为序列化程序会尝试同时发出String和Integer类型.我正在寻找创建一个自定义ContractResolver覆盖CreatePrimitiveContract以返回自定义JsonConverter类.但是,查看API时,似乎JsonConverter是基于类型创建的,而不是特定的对象值.

如何使用Json.NET序列化程序在C#中处理这种情况?

据推测,当一个自定义Json.Net类与某个自定义Json.Net类一起设置以检查属性的值并仅序列化非null属性时,该解决方案将涉及两个具有自定义setter的属性以使其他属性为null.

**假设示例**

// C# struct (or class)
[StructLayout(LayoutKind.Explicit)]
struct DojoPosition {
   [JsonProperty(PropertyName="position")]
   [FieldOffset(0)]
   public String StrPos;

   [JsonProperty(PropertyName="position")]
   [FieldOffset(0)]
   public Int32 IntPos;
}

// Serialization output
DojoPosition pos;
pos.StrPos = "only";
var output = JsonConvert.SerializeObject(pos);

// Output is: { "position": "only" }

pos.IntPos = 3;
var output = JsonConvert.SerializeObject(pos);

// Output is: { "position": 3 }

解决方法

我刚才有一个类似的问题.
对于合同的简单操作,请查看: Overriding the serialization behaviour in Json.Net

对于解析JsonPrimitiveContract重写CreateContract方法.

以下是基于我们解决方案的示例:

public class JsonDotNetContractResolver : DefaultContractResolver
   {
      protected override JsonContract CreateContract(Type objectType)
      {
         if (typeof(DojoPosition).IsAssignableFrom(objectType))
         {
            return new JsonPrimitiveContract(objectType.GetGenericArguments()[1])
                      {
                         CreatedType = typeof(object),// Not sure this will work for you,or is necessary...
                         IsReference = false,Converter = DojoPositionConverter,};
         }
         return base.CreateContract(objectType);
      }
      private class DojoPositionConverter : JsonConverter
      {
         public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer)
         {
            var dp = (DojoPosition) value;
            if(string.IsNullOrEmpty(dp.StrPos))
               serializer.Serialize(writer,dp.IntPos);
            else
               serializer.Serialize(writer,dp.StrPos);
         }
         public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer)
         {
            //...
         }
         public override bool CanConvert(Type objectType)
         {
            //....
         }
      }      
   }

如何确定从读者反序列化的类型是你的功课;)

相关文章

文章浏览阅读2.4k次。最近要优化cesium里的热力图效果,浏览...
文章浏览阅读1.2w次,点赞3次,收藏19次。在 Python中读取 j...
文章浏览阅读1.4k次。首字母缩略词 API 代表应用程序编程接口...
文章浏览阅读802次,点赞10次,收藏10次。解决一个JSON反序列...
文章浏览阅读882次。Unity Json和Xml的序列化和反序列化_uni...