Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get .NET Core JSON Body as dynamic object

My ASP.NET Core endpoint accepts a JSON form as its input and calls a method that expects a dynamic argument. I am attempting to call the method like this:

[HttpPost]
public IActionResult InitializeAction([FromBody] dynamic jsonData)
{
    return this.Ok(this.MyMethod(jsonData));
}

When I POST the JSON {"test": "value"} to this method, I would expect identical behavior to doing the following:

[HttpPost]
public IActionResult InitializeAction([FromBody] dynamic jsonData)
{
    return this.Ok(this.MyMethod(new {test = "value"}));
}

However, the JSON value retrieved using the [FromBody] parameter does not get converted to a standard .NET dynamic argument, and is instead a JsonDocument or JsonElement or something along those lines.

How do I receive or serialize the JSON from the HTTP Post as a .NET dynamic object?

like image 947
oobug Avatar asked Dec 10 '22 00:12

oobug


2 Answers

The incoming JSON body can be converted to a dynamic object by using JsonConvert.DeserializeObject on the JSON string.

[HttpPost]
public IActionResult InitializeAction([FromBody] dynamic jsonData)
{
    dynamic data = JsonConvert.DeserializeObject<dynamic>(jsonData.ToString());
    return this.Ok(this.MyMethod(data));
}
like image 191
oobug Avatar answered Jan 24 '23 13:01

oobug


UPDATE 31/07/2020

If convert object to ExpandoObject , you can access test directly.

    [HttpPost]
    [Route("/init")]
    public IActionResult Init([FromBody] dynamic jsonData)
    {
        var converter = new ExpandoObjectConverter();
        var exObjExpandoObject = JsonConvert.DeserializeObject<ExpandoObject>(jsonData.ToString(), converter) as dynamic;

        return this.Ok(this.MyMethod(exObjExpandoObject));
    }

    public string MyMethod(dynamic obj)
    {
        return obj.test;
    }

enter image description here

If use object , you need to get value by GetProperty.

    [HttpPost]
    [Route("/init2")]
    public IActionResult InitializeAction([FromBody] dynamic jsonData)
    {
        return this.Ok(this.MyMethod2(jsonData));
    }

    public string MyMethod2(dynamic obj)
    {
        JsonElement value = obj.GetProperty("test");
        return value.ToString();
    }

enter image description here





The ExpandoObject is a convenience type that allows setting and retrieving dynamic members. It implements IDynamicMetaObjectProvider which enables sharing instances between languages in the DLR. Because it implements IDictionary and IEnumerable, it works with types from the CLR. This allows an instance of the ExpandoObject to cast to IDictionary.

To use the ExpandoObject with an arbitrary JSON, you can write the following program:

    [HttpPost]
    [Route("/init")]
    public IActionResult InitializeAction([FromBody] dynamic jsonData)
    {
        var converter = new ExpandoObjectConverter();
        var exObj = JsonConvert.DeserializeObject<ExpandoObject>(jsonData.ToString(), converter);

        Debug.WriteLine($"exObj.test = {exObj?.test}, type of {exObj?.test.GetType()}") as dynamic;

        return this.Ok(exObj.test);
    }

Screenshots of Test:

enter image description here

enter image description here

Reference
Working with the Dynamic Type in C#

like image 33
Michael Wang Avatar answered Jan 24 '23 13:01

Michael Wang