0

Hi would need some help / advice. I would need to build an endpoint which takes in an argument of key value pairs, specifically Dictionary<string,dynamic> as the values may dynamic. Below is a my code snippet:

    [ApiController]
    [Route("api/General/[controller]")]
    public class TestController : Controller
    {
        private readonly ILogger<TestController> _logger;

        public TestController(ILogger<TestController> logger)
        {
            _logger = (ILogger<TestController>)logger;
        }

        [HttpPost]
        public async Task<IActionResult> OnPost([FromBody] Dictionary<string,dynamic> incomingData)
        {
            string item01Id = incomingData["item01Id"];
            int item01Value = incomingData["item01Value"];
            string item02Id = incomingData["item02Id"];
            string item02Value = incomingData["item02Value"];

            return Ok();
        }
    }

For the test I did a Post with a json body of:

{
  "item01Id": "Item 01",
  "item01Value": 133,
  "item02Id": "Item 02",
  "item02Value": "some value"
}

Seems it was unable to assign the the value into the various .net variables as the dynamic values were of type System.Text.Json.JsonElement as shown by the exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot implicitly convert type 'System.Text.Json.JsonElement' to 'string'

I have found a way by using the JsonElement's ValueKind. But I was wondering if there is a way where by I can deserialize it into a .net type directly instead of a JsonElement.

Added for additional context: Locals

Thanks in Advance

Glen Chia
  • 1
  • 4
  • I have just tried it but seems like its still not working. Error was System.Collections.Generic.KeyNotFoundException: The given key 'item01Id' was not present in the dictionary. Seems like it is because now "incomingData" is now treated as a key and the values are whatever inside it. { "incomingData" : { "item01Id": "Item 01", "item01Value": 133, "item02Id": "Item 02", "item02Value": "some value" } } – Glen Chia Oct 20 '21 at 07:33
  • What about changing `Dictionary` to `Dictionary`? – AmirJabari Oct 20 '21 at 07:42
  • @AmirJabari yupp just did, and it was still receiced as _System.Text.Json.JsonElement_ instead of a _string_ – Glen Chia Oct 20 '21 at 07:48
  • Your incoming data is just some simple data types like `int`, `uint`, and `string`? – AmirJabari Oct 20 '21 at 07:57
  • Try this: https://stackoverflow.com/questions/58138793/system-text-json-jsonelement-toobject-workaround – sr28 Oct 20 '21 at 07:59
  • If it is just some simple data types I recommend to change incoming data to `Dictionary` and use `GetString` and `TryGetInt32` methods for simplicity. – AmirJabari Oct 20 '21 at 08:02
  • Yea actually as I had a work around whereby I used an extension method checked the ValueKind property of the JsonElement before converting it to the appropriate value. Was just wondering if there was a more elegant way. Thanks @AmirJabari for your help. – Glen Chia Oct 20 '21 at 08:13
  • @sr28 Thanks! But yea actually I did a similar thing whereby I had an extension method which checks the ValueKind property before performing some conversion. Just was wondering if there was a more elegant way. – Glen Chia Oct 20 '21 at 08:15
  • @GlenChia - does Newtonsoft provide what you need instead of System.Text.Json? – sr28 Oct 20 '21 at 08:38
  • @sr28 originally when I came out with a work around I was using _System.Text.Json_ but since the [reference](https://stackoverflow.com/questions/58138793/system-text-json-jsonelement-toobject-workaround) was doing something similar i did not look into Newtonsoft. – Glen Chia Oct 20 '21 at 08:47
  • If all you're doing is just trying to use those same properties, but they maybe of different types, why not just deserialize into an object with the properties as object? – sr28 Oct 20 '21 at 10:27

0 Answers0