Web API 2是否可自定义模型绑定规则实现JSON到指定模型的映射?
解决方案
Web API 2 默认使用 Json.NET 处理 JSON 序列化/反序列化,你可以通过自定义 JsonConverter 的方式实现全局统一的绑定规则,无需在每个控制器重复编写逻辑。
首先修正你示例代码的笔误:model1 和 model2 应该是类而非 string 类型,修正后的模型定义如下:
public class model1 { public string name { get; set; } public string value { get; set; } } public class model2 { public string ident { get; set; } public IEnumerable<model1> model { get; set; } }
步骤1:实现自定义JsonConverter
创建转换器类,实现JSON对象到IEnumerable<model1>的转换逻辑:
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; public class Model1CollectionConverter : JsonConverter { public override bool CanConvert(Type objectType) { // 匹配所有 IEnumerable<model1> 类型的属性 return objectType == typeof(IEnumerable<model1>); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var result = new List<model1>(); // 加载JSON节点 var jObject = JObject.Load(reader); // 遍历所有属性,转成model1实例 foreach (var prop in jObject.Properties()) { result.Add(new model1 { name = prop.Name, value = prop.Value.ToString() }); } return result; } // 如果不需要将model2序列化成对应格式的JSON,可以不用实现该方法 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var list = (IEnumerable<model1>)value; var jObject = new JObject(); foreach (var item in list) { jObject.Add(item.name, item.value); } jObject.WriteTo(writer); } }
步骤2:全局注册转换器
在WebApiConfig.cs的Register方法中注册该转换器,即可全局生效:
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 其他Web API配置代码... // 注册自定义转换器 config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new Model1CollectionConverter()); } }
效果验证
你给出的输入JSON { "ident": "moo", "model": { "fish": "sticks" } } 会自动绑定为符合要求的model2实例:
ident属性值为"moo"model属性包含1个model1实例,name为"fish",value为"sticks"
如果只需要针对部分IEnumerable<model1>属性生效,不需要全局注册的话,也可以直接在属性上加[JsonConverter(typeof(Model1CollectionConverter))]特性即可。
内容的提问来源于stack exchange,提问作者David Hubner
相关产品推荐
相关产品推荐

