Reputation: 18630
I have this incoming request with this payload
{
count : 10,
supplier : {
id : 342,
name : 'test'
},
title : 'some title'
}
and I have this model in my c# code
class SomeModel
{
public string Title { get; set; }
public int SupplierId { get; set; }
public double Amount { get; set; }
}
This is my controller method
public IActionResult Foo(SomeModel data)
{
//...
}
I would like to map the property count
in request payload to Amount
property in my c# model and mapping the value of supplier.id
into SupplierId
.
I'm using Newtonsoft Json.NET library for binding
Upvotes: 0
Views: 96
Reputation: 9642
Obviously the simplest way is to create a class corresponding to payload stucture like this
public class SomeModel
{
public string Title { get; set; }
public double Count { get; set; }
public Supplier Supplier { get; set; }
}
public class Supplier
{
public int Id { get; set; }
public string Name { get; set; }
}
Another iteration could be using JsonProperty
attribute for Amount
and SupplierId
property making use of Supplier
class SomeModel
{
public string Title { get; set; }
[JsonProperty("count")]
public double Amount { get; set; }
public int SupplierId => Supplier.Id;
public Supplier Supplier { get; set; }
}
class Supplier
{
public int Id { get; set; }
public string Name { get; set; }
}
But if you like to stick with your current model you will need to create a custom converter. And what I can suggest you
public class NestedPropertyConverter : JsonConverter
{
private string[] _properties;
public NestedPropertyConverter(string propertyChain)
{
//todo: check if property chain has valid structure
_properties = propertyChain.Split('.');
}
public override bool CanWrite => false;
public override bool CanConvert(Type objectType) => true;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = (JToken)serializer.Deserialize(reader);
foreach (string property in _properties)
{
token = token[property];
if (token == null) //if property doesn't exist
return existingValue; //or throw exception
}
return token.ToObject(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Basically, the converter allows to bind nested properties. Usage
class SomeModel
{
public string Title { get; set; }
[JsonConverter(typeof(NestedPropertyConverter), "id")]
[JsonProperty("supplier")] //its necessary to specify top level property name
public int SupplierId { get; set; }
[JsonProperty("count")]
public double Amount { get; set; }
}
Note
I also tested the following payload
{
count : 10,
supplier : {
id : 342,
name : "test",
test: {
val: 55
}
},
title : "some title"
}
and config for property
[JsonConverter(typeof(NestedPropertyConverter), "test.val")]
[JsonProperty("supplier")]
public int SupplierId { get; set; }
and it works fine.
Upvotes: 2