C# 使用Newtonsoft.JSON将一些JSON属性反序列化到子对象

C# 使用Newtonsoft.JSON将一些JSON属性反序列化到子对象,c#,asp.net,json,asp.net-web-api,json.net,C#,Asp.net,Json,Asp.net Web Api,Json.net,我有一个JSON格式的字符串: { "hr": "12:56", "vs": [ { "pre": "73833", "a": true, "posx": "-46.688962875", "posy": "-23.632046625" }, { "pre": "73722", "a": t

我有一个JSON格式的字符串:

{
    "hr": "12:56",
    "vs": [
        {
            "pre": "73833",
            "a": true,
            "posx": "-46.688962875",
            "posy": "-23.632046625"
        },
        {
            "pre": "73722",
            "a": true,
            "posx": "-46.773388125",
            "posy": "-23.68939025"
        }                               
    ]
}
我想将JSON反序列化到此类:

public class Tracking
{
    [JsonProperty(PropertyName = "hr")]
    public string Hour { get; set; }

    [JsonProperty(PropertyName = "vs")]
    public IList<Vehicle> Vehicles { get; set; }
}
相反,我想将posx和posy属性反序列化为一个名为Position的子类,该子类具有X和Y属性:

public class Position
{
    [JsonProperty (PropertyName = "posx")]
    public string Y {get; set; }

    [JsonProperty (PropertyName = "posy")]
    public string X {get; set; }
}
导致以下车辆等级:

我打算在我的系统中的更多位置使用Position类,不想重复这些属性。但是当使用新结构反序列化时,Position属性返回null

{
    "hr": "13:08",
    "vs": [
        {
            "pre": "73833",
            "a": true,
            "Position": null
        },
        {
            "pre": "73722",
            "a": true,
            "Position": null
        }    
    ]
}

我该怎么做才能使这段代码正常工作?

如果您使用Newtonsoft,您应该能够使用Vehicle myVehicle=JsonConvert进行反序列化。反序列化对象有几种方法可以实现您想要的结果。 最快的方法是对原始车辆类别进行几项更改:

添加一个新的Position属性并用[JsonIgnore]标记它 将X和Y属性设置为私有,并对其进行更改,以便它们写入和读取位置对象。 生成的类应如下所示:

public class Vehicle
{
    [JsonProperty(PropertyName = "pre")]
    public string Prefix { get; set; }

    [JsonIgnore]
    public Position Position { get; set; }

    [JsonProperty(PropertyName = "posx")]
    private string Y
    {
        get { return Position != null ? Position.Y : null; }
        set
        {
            if (Position == null) { Position = new Position(); }
            Position.Y = value;
        }
    }

    [JsonProperty(PropertyName = "posy")]
    private string X
    {
        get { return Position != null ? Position.X : null; }
        set
        {
            if (Position == null) { Position = new Position(); }
            Position.X = value;
        }
    }
}
演示小提琴:

如果您不喜欢这个想法,另一个选择是为您的车辆类别定制JsonConverter:

然后,使用[JsonConverter]属性标记您的车辆类别,将其与转换器关联:

[JsonConverter(typeof(VehicleConverter))]
public class Vehicle
{
    [JsonProperty(PropertyName = "pre")]
    public string Prefix { get; set; }

    public Position Position { get; set; }
}

Demo fiddle:

反序列化什么?我想我们需要看看您想要反序列化的json是如何更新的。您应该将序列化部分与程序的其余部分分开。如果您想更改对象层次结构,请创建一个适配器,否则您很快就会遇到一次又一次的黑客攻击,以获得想要的json格式。最好将两者分开。您的Json似乎与您的车辆类别不匹配。JsonProperty需要与Json字符串中的名称匹配。p=>pre,px=>posx等等……您的json仍然与您的类不匹配。如果数据结构有问题,请尝试使用
public class Vehicle
{
    [JsonProperty(PropertyName = "pre")]
    public string Prefix { get; set; }

    [JsonIgnore]
    public Position Position { get; set; }

    [JsonProperty(PropertyName = "posx")]
    private string Y
    {
        get { return Position != null ? Position.Y : null; }
        set
        {
            if (Position == null) { Position = new Position(); }
            Position.Y = value;
        }
    }

    [JsonProperty(PropertyName = "posy")]
    private string X
    {
        get { return Position != null ? Position.X : null; }
        set
        {
            if (Position == null) { Position = new Position(); }
            Position.X = value;
        }
    }
}
class VehicleConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Vehicle);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject obj = JObject.Load(reader);
        Vehicle veh = new Vehicle();
        serializer.Populate(obj.CreateReader(), veh);
        Position pos = new Position();
        serializer.Populate(obj.CreateReader(), pos);
        veh.Position = pos;
        return veh;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Vehicle veh = (Vehicle)value;
        JObject obj = JObject.FromObject(veh.Position, serializer);
        obj.AddFirst(new JProperty("pre", veh.Prefix));
        obj.WriteTo(writer);
    }
}
[JsonConverter(typeof(VehicleConverter))]
public class Vehicle
{
    [JsonProperty(PropertyName = "pre")]
    public string Prefix { get; set; }

    public Position Position { get; set; }
}