Home > Software engineering >  Transforming JSON before binding to an object in a .net core controller
Transforming JSON before binding to an object in a .net core controller

Time:01-18

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() {}
}
  • Related