gpt4 book ai didi

c# - 如何使用 json.net "inline"生成 json 中的属性

转载 作者:行者123 更新时间:2023-11-30 12:40:45 25 4
gpt4 key购买 nike

我在我的一个类中有一个属性,我试图用 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",
"SteeringWheel": {
"HornButtonManufacturer": null,
"ManufacturerEmail": "test@demo.com"
}
}

显然,我可以通过在 ISteeringWheel 中同时拥有 ManufacturerEmailPartNumber 并将一个或另一个 null 并设置为忽略空值,但我宁愿在我的类中正确分隔事物。

我在这里用上面的代码创建了一个 fiddle :https://dotnetfiddle.net/C9RPy9

最佳答案

一种方法是为 ISteeringWheelIdentifier 创建您自己的自定义 json 反序列化器,您应该在其中为每个方向盘标识符类型实现所需的反序列化结果(参见 http://www.newtonsoft.com/json/help/html/CustomJsonConverter.htm )作为示例。然后,您应该为您的标识符属性 [JsonConverter(typeof([您的新转换器的名称]))] 设置一个 JsonConverter 属性,它将按照您指定的方式进行反序列化。

编辑 - 在实际实现时,事实证明要获得所需的行为有点棘手。您需要创建的转换器是一个用于 ISteeringWheel 接口(interface)的转换器。在其中,遍历所有属性,直到到达标识符属性,然后处理其序列化。举个例子:

    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; }
}
}

现在剩下的就是将属性添加到汽车类:

public class Car
{
public string CarBrand { get; set; }

[JsonConverter(typeof(SteeringWheelJsonConverter))]
public ISteeringWheel SteeringWheel { get; set; }

}

关于c# - 如何使用 json.net "inline"生成 json 中的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40862660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com