如何在API返回IEnumerable<AnimalModel>时包装对象为数组格式?
解决方案
你不需要把对象序列化成字符串,直接返回强类型集合即可,同时通过两种方式实现目标JSON结构:
方式一:修改API返回类型(推荐)
创建专门的响应包装类,把集合作为它的属性,这样类型安全且易于维护:
- 定义包装类:
public class AnimalResponse { // 属性名和目标JSON键名一致,也可通过[JsonPropertyName]特性指定 public IEnumerable<AnimalModel> MyAnimal { get; set; } }
- 包装原结果并返回:
// 将单个AnimalModel对象转换为集合 var animalList = new List<AnimalModel> { originalResult }; // 返回包装类实例 return new AnimalResponse { MyAnimal = animalList };
最后把API的返回类型从IEnumerable<AnimalModel>改为AnimalResponse,序列化后就能得到你想要的JSON结构。
方式二:保留原返回类型,通过序列化配置实现包裹
如果无法修改API返回类型,可通过自定义JSON序列化转换器,让集合在序列化时自动被包裹在myAnimal键下:
针对ASP.NET Core(System.Text.Json)
- 编写自定义转换器:
public class AnimalListConverter : JsonConverter<IEnumerable<AnimalModel>> { // 反序列化逻辑(需处理请求时实现) public override IEnumerable<AnimalModel> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using var doc = JsonDocument.ParseValue(ref reader); var animalArray = doc.RootElement.GetProperty("MyAnimal"); return JsonSerializer.Deserialize<IEnumerable<AnimalModel>>(animalArray.GetRawText(), options); } // 序列化逻辑,实现外层包裹 public override void Write(Utf8JsonWriter writer, IEnumerable<AnimalModel> value, JsonSerializerOptions options) { writer.WriteStartObject(); writer.WritePropertyName("MyAnimal"); JsonSerializer.Serialize(writer, value, options); writer.WriteEndObject(); } }
- 在Program.cs/Startup.cs中注册转换器:
builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new AnimalListConverter()); });
- 直接返回集合:
return new List<AnimalModel> { originalResult };
此时API返回IEnumerable<AnimalModel>类型,但序列化后的JSON会自动带上myAnimal外层包装。
针对使用Newtonsoft.Json的场景
如果项目用的是Newtonsoft.Json,可通过自定义契约解析器实现:
public class AnimalListContractResolver : DefaultContractResolver { protected override JsonContract CreateContract(Type objectType) { var contract = base.CreateContract(objectType); if (objectType == typeof(IEnumerable<AnimalModel>) || objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(List<>)) { contract.Converter = new AnimalListNewtonsoftConverter(); } return contract; } } public class AnimalListNewtonsoftConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(IEnumerable<AnimalModel>); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jo = JObject.Load(reader); return jo["MyAnimal"].ToObject<IEnumerable<AnimalModel>>(serializer); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteStartObject(); writer.WritePropertyName("MyAnimal"); serializer.Serialize(writer, value); writer.WriteEndObject(); } }
然后注册契约解析器:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.ContractResolver = new AnimalListContractResolver(); });
内容的提问来源于stack exchange,提问作者ianuwebee
相关产品推荐
相关产品推荐

