簡體   English   中英

將 C# List 序列化為具有內部數組的復數命名對象

[英]Serialize C# List into plural named object with an inner array

我們有一個遺留的 WCF 產品,它使用 XML 序列化屬性序列化 POCO。

這是列表的示例,具有 XmlArray/XmlArrayItem 屬性。 有點像 [ 如何為 List<Custom> 實現設置 XmlArrayItem 元素名稱?

[XmlArray("Things", Order = 4), XmlArrayItem("Thing")]
public List<Thing> Things { get; set; }

這會產生 XML 響應:

<m:Things>
  <m:Thing>
  ...
  </m:Thing>
  <m:Thing>
  ...
  </m:Thing>
  <m:Thing>
  ...
  </m:Thing>
</m:Things>

並且(通過外部翻譯)轉換為這個 Json 響應(具有內部數組的復數命名對象(單數命名)Json 響應):

"Things": {
"Thing": [
    {
        ...
    },
    {
        ...
    }
]}

現在,我們有一個沒有 XML 輸出的 .NET Core 2.1 應用程序——只有 Json。 所以我想將 List 序列化到這個 Json 響應中,這樣我就不會破壞任何期待這個響應的客戶端。

我意識到我可以圍繞 List 編寫一個包裝器,但是我有大約 40 個這樣的 List 要做,並且調用代碼會變得非常模糊。 事實上,如果我執行 Paste Special > Paste JSON as classes,它看起來像:

  class Model
  {
     public ThingsWrapper Things { get; set; }
  }

    public class ThingsWrapper
    {
        public Thing[] Thing { get; set; }
    }

    public class Thing
    {
...
    }

called with var x = Things.Thing; // (yuck)

基於https://dotnetfiddle.net/vUQKV1 - 我試過這個 JsonConverter。 然而,結果是這樣的,這是相反的。 我需要事物作為對象和事物作為數組。

{
  "things": [
    {
      "thing": {
        "Id": 1
      }
    },
    {
      "thing": {
        "Id": 2
      }
    }
  ]
}
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class Program
{
    public static void Main()
    {
        var foo = new Foo();
        foo.Things = new List<Foo.Thing>{new Foo.Thing{Id = 1}, new Foo.Thing{Id = 2}};
        Console.WriteLine(JsonConvert.SerializeObject(foo, Formatting.Indented));
    }
}

class Foo
{
    [JsonProperty("things")]
    [JsonConverter(typeof(CustomArrayConverter<Thing>), "thing")]
    public List<Thing> Things
    {
        get;
        set;
    }

    public class Thing
    {
        public int Id
        {
            get;
            set;
        }
    }
}

class CustomArrayConverter<T> : JsonConverter
{
    string PropertyName
    {
        get;
        set;
    }

    public CustomArrayConverter(string propertyName)
    {
        PropertyName = propertyName;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JArray array = new JArray(JArray.Load(reader).Select(jo => jo[PropertyName]));
        return array.ToObject(objectType, serializer);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        IEnumerable<T> items = (IEnumerable<T>)value;
        JArray array = new JArray(items.Select(i => new JObject(new JProperty(PropertyName, JToken.FromObject(i, serializer)))));
        array.WriteTo(writer);
    }

    public override bool CanConvert(Type objectType)
    {
        // CanConvert is not called when the [JsonConverter] attribute is used
        return false;
    }
}

感謝@Brian 在 Json.NET 中的 Name 數組元素? https://dotnetfiddle.net/vUQKV1 ,它為我指明了正確的方向。

class CustomArrayConverter<T> : JsonConverter
    {
        string PropertyName { get; set; }

        public CustomArrayConverter(string propertyName)
        {
            PropertyName = propertyName;
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JArray array = new JArray(JArray.Load(reader).Select(jo => jo[PropertyName]));
            return array.ToObject(objectType, serializer);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            IEnumerable<T> items = (IEnumerable<T>)value;
            JObject jObject = new JObject(new JProperty(PropertyName, new JArray(items.Select(i => JToken.FromObject(i, serializer)))));
            jObject.WriteTo(writer);
        }

        public override bool CanConvert(Type objectType)
        {
            // CanConvert is not called when the [JsonConverter] attribute is used
            return false;
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM