Reputation: 11
I have this string in JSON format:
{
"hr": "12:56",
"vs": [
{
"pre": "73833",
"a": true,
"posx": "-46.688962875",
"posy": "-23.632046625"
},
{
"pre": "73722",
"a": true,
"posx": "-46.773388125",
"posy": "-23.68939025"
}
]
}
I want to deserialize the JSON to this class:
public class Tracking
{
[JsonProperty(PropertyName = "hr")]
public string Hour { get; set; }
[JsonProperty(PropertyName = "vs")]
public IList<Vehicle> Vehicles { get; set; }
}
The Vehicle
class currently has the following attributes:
public class Vehicle
{
[JsonProperty (PropertyName = "pre")]
public string Prefix {get; set; }
[JsonProperty (PropertyName = "posx")]
public string Y {get; set; }
[JsonProperty (PropertyName = "posy")]
public string X {get; set; }
}
Instead, I would like to deserialize the posx
and posy
attributes into a child class called Position
with X
and Y
properties:
public class Position
{
[JsonProperty (PropertyName = "posx")]
public string Y {get; set; }
[JsonProperty (PropertyName = "posy")]
public string X {get; set; }
}
Resulting in the following Vehicle
class:
public class Vehicle
{
[JsonProperty (PropertyName = "pre")]
public string Prefix {get; set; }
public Position Position {get; set; }
}
I intend to use the Position
class on more places on my system and would not like to repeat these properties. But when deserializing with the new structure, the Position
property returns null.
{
"hr": "13:08",
"vs": [
{
"pre": "73833",
"a": true,
"Position": null
},
{
"pre": "73722",
"a": true,
"Position": null
}
]
}
What can I do to make this code work?
Upvotes: 0
Views: 3642
Reputation: 129687
There are a couple of ways you can achieve the result you want.
The quickest way is to make a couple of changes to your original Vehicle
class:
Position
property and mark it with [JsonIgnore]
X
and Y
properties private and change them so that they write to, and read from, the Position
object.The resulting class should look like this:
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;
}
}
}
Demo fiddle: https://dotnetfiddle.net/5zT5Rf
If you don't like that idea, another option is to make a custom JsonConverter
for your Vehicle
class:
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);
}
}
Then, mark your Vehicle
class with a [JsonConverter]
attribute to tie it to the converter:
[JsonConverter(typeof(VehicleConverter))]
public class Vehicle
{
[JsonProperty(PropertyName = "pre")]
public string Prefix { get; set; }
public Position Position { get; set; }
}
Demo fiddle: https://dotnetfiddle.net/HRSRa9
Upvotes: 1
Reputation: 489
If you use Newtonsoft you should be able to deserialize using Vehicle myVehicle = JsonConvert.DeserializeObject<Vechicle)(myString)
given that:
Upvotes: 0