c# – 如何使用json.net“内联”生成json中的属性
发布时间:2020-12-15 22:38:00 所属栏目:百科 来源:网络整理
导读:我在我的一个类中有一个属性,我正在尝试使用json.net进行序列化,我想“内联”,这意味着,我不希望将属性嵌套到具有属性名称的元素中,但其内容直接在其母公司内. 这是一个例子,假设我有以下类结构: public interface ISteeringWheelIdentifier {}public inter
我在我的一个类中有一个属性,我正在尝试使用json.net进行序列化,我想“内联”,这意味着,我不希望将属性嵌套到具有属性名称的元素中,但其内容直接在其母公司内.
这是一个例子,假设我有以下类结构: public interface ISteeringWheelIdentifier {} public interface ISteeringWheel { ISteeringWheelIdentifier Identifier {get;} } public class ManufacturerIdentifier : ISteeringWheelIdentifier { public string ManufacturerEmail {get; set;} } public class PartNumberIdentifier : ISteeringWheelIdentifier { public string PartNumber {get; set;} } public class ClassicSteeringWheel : ISteeringWheel { public ClassicSteeringWheel(ManufacturerIdentifier identifier) { Identifier = identifier; } public string HornButtonManufacturer {get; set;} public ISteeringWheelIdentifier Identifier {get;private set;} } public class ModernSteeringWheel : ISteeringWheel { public ModernSteeringWheel(PartNumberIdentifier identifier) { Identifier = identifier; } public string TouchpadManufacturer {get; set;} public ISteeringWheelIdentifier Identifier {get;private set;} } public class Car { public string CarBrand {get; set;} public ISteeringWheel SteeringWheel {get; set;} } 如果我尝试使用以下代码序列化两个测试对象: public static void Main() { var car1 = new Car{CarBrand="Ford",SteeringWheel = new ModernSteeringWheel(new PartNumberIdentifier{PartNumber = "123456"})}; var json = JsonConvert.SerializeObject(car1,Formatting.Indented); Console.WriteLine(json); var car2 = new Car{CarBrand="Toyota",SteeringWheel = new ClassicSteeringWheel(new ManufacturerIdentifier{ManufacturerEmail = "test@demo.com"})}; json = JsonConvert.SerializeObject(car2,Formatting.Indented); Console.WriteLine(json); } 你得到这个结果: { "CarBrand": "Ford","SteeringWheel": { "TouchpadManufacturer": null,"Identifier": { "PartNumber": "123456" } } } { "CarBrand": "Toyota","SteeringWheel": { "HornButtonManufacturer": null,"Identifier": { "ManufacturerEmail": "test@demo.com" } } } 但是,对于我的情况,标识符只是一种管理方向盘识别方式的方法,我不需要拥有该属性.由此产生的Json我期待如下: { "CarBrand": "Ford","SteeringWheel": { "TouchpadManufacturer": null "PartNumber": "123456" } } { "CarBrand": "Toyota","ManufacturerEmail": "test@demo.com" } } 显然,我可以通过在ISteeringWheel中同时使用ManufacturerEmail和PartNumber并将一个或另一个null设置为忽略空值来实现,但我宁愿在我的类中正确分隔事物. 我在这里用上面的代码创建了一个小提琴:https://dotnetfiddle.net/C9RPy9 解决方法
一种方法是为ISteeringWheelIdentifier创建自己的自定义json反序列化器,在其中您应该为每个方向盘标识符类型实现所需的反序列化结果(请参阅
http://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm)以获取示例.然后你应该为你的Identifier属性设置一个JsonConverter属性[JsonConverter(typeof([你的新转换器的名称]))]然后你会指定它反序列化.
编辑 – 当实际实现它时,结果是有点琐碎以获得所需的行为.您需要创建的转换器是ISteeringWheel接口的转换器.在其中,遍历所有属性,直到获得标识符属性,并处理其序列化.举个例子: public class SteeringWheelJsonConverter : JsonConverter { public override bool CanConvert(Type objectType) { return typeof(ISteeringWheel).IsAssignableFrom(objectType); } public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer) { JObject jo = new JObject(); Type type = value.GetType(); foreach (var prop in type.GetProperties()) { if (prop.CanRead) { var propVal = prop.GetValue(value,null); if (prop.Name == "Identifier") { // Iterate over all properties of the identifier,but don't add the identifier object itself // to the serialized result. Type identifierType = propVal.GetType(); foreach (var identifierProp in identifierType.GetProperties()) { var identifierPropVal = identifierProp.GetValue(propVal,null); jo.Add(identifierProp.Name,identifierPropVal != null ? JToken.FromObject(identifierPropVal,serializer) : null); } } else { // Add the property to the serialized result jo.Add(prop.Name,propVal != null ? JToken.FromObject(propVal,serializer) : null); } } } jo.WriteTo(writer); } public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer) { throw new NotImplementedException(); } public override bool CanRead { get { return false; } } } 现在剩下的就是将属性添加到car类: public class Car { public string CarBrand { get; set; } [JsonConverter(typeof(SteeringWheelJsonConverter))] public ISteeringWheel SteeringWheel { get; set; } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |