![](/img/trans.png)
[英]Serialize array of objects as one object with a named property for each object in C# with JSON serializer
[英]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.