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?
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));
}
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;
}
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();
}
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:
Reference
Working with the Dynamic Type in C#
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With