I'm trying to bind the JSON, that's coming from a source I cannot control, to a custom class in a controller. The problem that I ran to is the fact that the array of values are sent in format [{'value': 'value1'}, [{'value':'value2'}]. I know that I can create an object that would have one field 'value' and the binding would work, but I want to avoid that and get all the values from the request bound to a string list.
I have this controller method
public async Task<IActionResult> UploadData(List<DataModel> values)
And here's how I'd like the DataModel to look like.
public class DataModel
{
public string? a{ get; set; }
public List<string>? b{ get; set; }
}
And here's how the example of data
[{
"a": "name",
"b": [
{
"value": "one"
},
{
"value": "two"
}
]
}]
Is there a way to achieve this, preferably using an attriubte?
CodePudding user response:
Leave the binding object exactly as it should be to map from the source you can't control and just make a custom getter for the object that transforms it in a list like you want. Using automapper or other suggested third party libs will add an unnecessary layer of complexity.
public class DataModel
{
public string? a { get; set; }
public List<ObjectFromSource> b{ get; set; }
[NonSerialized]
public string getb()
{
//returns a string list
return string.Join(",", b.Select(x => x.value));
}
}
public class ObjectFromSource
{
public string? value { get; set; }
}
then when you need the value around you just call
DataModel x = new DataModel();
x.getb();
CodePudding user response:
the simpliest way is to change the action input parameter type
public async Task<IActionResult> UploadData(JArray jArr)
{
List<DataModel> values = jArr.Select(ja => new DataModel { a = (string)ja["a"],
b = ja["b"].Select(b => (string)b["value"]).ToList() }).ToList();
//your code
}
another way is to use a JsonConstructor
public class DataModel
{
public string? a { get; set; }
public List<string>? b { get; set; }
[Newtonsoft.Json.JsonConstructor]
public DataModel (JArray b)
{
this.b= b.Select(b => (string)b["value"]).ToList();
}
public DataModel() {}
}