dynamic c# ValueKind = Object
Asked Answered
P

7

27

As i'm trying to access object values using JsonSerializer.Deserialize using debugger.
enter image description here

Here is my result which i'm having below.

  OtpData = ValueKind = Object : "{
        "OTP":"3245234",
        "UserName":"mohit840",
        "type":"SuperAdmin"
    }"

As i try to access it using var Data = JsonSerializer.Deserialize(OtpData) it gives me following error below.
enter image description here

How can i access the inside and get values of the following object.

"OTP":"3245234",
        "UserName":"mohit840",
        "type":"SuperAdmin"

Update :

        [AllowAnonymous]
        [HttpPost("ValidateOTP")]
        public IActionResult ValidOTP(dynamic OtpData)
        {
            bool Result = false;
            var Data = JsonSerializer.Deserialize(OtpData);            
            if (OtpData.type == "SuperAdmin")
            {
                Users _Users = _Context.Users.FirstOrDefault(j => j.Username == "");
                if (_Users != null)
                {
                    _Users.OTP = OtpData.OTP;                    
                    _Users.VerififedOTP = true;
                    _Context.SaveChanges();
                    Result = true;
                }
            }
            else
            {
                Staff _Staff = _Context.Staffs.FirstOrDefault(j => j.Username == "");
                if (_Staff != null)
                {
                    _Staff.OTP = OtpData.OTP;                    
                    _Staff.VerififedOTP = true;
                    _Context.SaveChanges();
                    Result = true;
                }
            }

            return Ok(new { Result = Result });
        } 

Update 2: As i'm posting this by Postman application.

{
    "OTP":"3245234",
    "UserName":"mohit840",
    "type":"SuperAdmin"
}
Phyllous answered 27/7, 2020 at 19:3 Comment(10)
Why are you accepting a dynamic if you know it's a string and it only works if it's a string? You shouldn't be using dynamic typing unless you actually need it. Not having to deal with problems like this is one of the many reasons why.Graehl
So, what is the actual type of the dynamic OptData, returned by OptData.GetType()? It's probably not any of the types accepted by any of the overloads to JsonSerializer.Deserialize(). But since you're using dynamic this sort of error can only be caught in runtime not compile time.Across
@Across i'll added code i just need to access those values how can i do so ...?Phyllous
I'll update again for the actual type.Phyllous
@Across even if i use object keyword i t still shows me same result.Phyllous
@NamanKumar You will not get a runtime binder exception if you're not using dynamic. That exception is specific to dynamically compiling code. If the types of your code aren't valid, they'll be compiler errors instead.Graehl
@Graehl How can i access these objects dynamically as i don't want to hard code them which i could have used before.Phyllous
Did you ever determine the actual, concrete type of OtpData? You've tagged this with both json.net and system.text.json so we really have no way of guessing what that really is. I mean specifically what is returned if you examine the value of OtpData.GetType().FullName in the debugger.Across
ok @Across i'll update againPhyllous
@NamanKumar Your input is always a string. It's never anything else. Making it dynamic doesn't change that at all. The documentation of whatever deserialier you're using will cover how to inspect objects that don't have a static structure, but that's based on the output, not the input.Graehl
J
12

From new release of Asp.net Core 3.0 Microsoft has come with System.Text.Json which introduce new JsonElement ValueKind so ValueKind is from System.Text.Json library and JsonConvert is from Newtonsoft library.

Resolution :-

it is possible that you have mixed both the library while Serializing the object you may have used Newtonsoft.Json and while Deserilizing you may have used System.Text.Json or vice versa.

Jason answered 4/1, 2021 at 15:58 Comment(0)
T
10
public async Task<dynamic> PostAsync([FromBody] Object post)
{
     var data = JsonConvert.DeserializeObject<dynamic>(post.ToString());
Trumantrumann answered 21/4, 2022 at 14:13 Comment(1)
This is a good and working answer which I was looking for too. But instead of public async Task<dynamic>, public async Task<IActionResult> would be better in web api scenarios.Dogma
A
4

ASP.Net core uses inbuilt System.Text.Json based JsonConverter for binding the model from json input that is sent. If you are using Newtonsoft Json in your project, you need to configure this to use it for the model binding.

For that you need to install the nuget package "Microsoft.AspNetCore.Mvc.NewtonsoftJson" and add the line "builder.Services.AddControllers().AddNewtonsoftJson();" to Program.cs. This will serilaize the expando object properly by name and value.

Archidiaconal answered 27/4, 2022 at 12:46 Comment(1)
Thank you very much - I was trying to implement a PATCH with optional (nullable) values using an OpenApi / client generated from .net's "Connected Services". This fixed my issue.Abercromby
F
1

Quite late to this post but I've just run into the same thing, and a quick workaround is to send the JSON object as a string and then in the controller just deserialize it back into the model. It may be hacky but it certainly works for me quite nicely.

Freaky answered 4/12, 2023 at 11:13 Comment(0)
S
0

Refer System.Text.Json.JsonSerializer instead of newton soft json serializer

class OTPData{ public string OTP {get;set} ....... }

var result = System.Text.Json.JsonSerializer.Deserialize<OTPData> 
(response.ToString());

string otp = result.OTP;
string username = result.UserName;
string type = result.type;
Sherrellsherrer answered 8/9, 2021 at 7:23 Comment(0)
L
0

The ValueKind is json data in System.Text.Json format. We can convert it to any type using Newtonsoft.Json as below:

public class OtpData
{
  public string Otp { get; set; } 
  public string UserName { get; set; } 
  public string Type { get; set; } 
}
    
public OtpData GetOtpData(object otpData)
{
  var jsonString = ((System.Text.Json.JsonDocument)otpData).RootElement.GetRawText();
  return JsonConvert.DeserializeObject<OtpData>(jsonString);
}
Lavelle answered 24/5, 2022 at 11:38 Comment(0)
D
-1
public class OtpData { 
[JsonPropertyName("OTP")] 
public string Otp { get; set; } 
[JsonPropertyName("UserName")] 
public string UserName { get; set; } 
[JsonPropertyName("type")] 
public string Type { get; set; } 
} 
public IActionResult ValidOTP(OtpData data) 
{ 
bool result = false; 
if (data.Type.ToString() == "SuperAdmin") { } 
} 
Diller answered 26/9, 2020 at 8:46 Comment(1)
Please provide a description.Ruelle

© 2022 - 2024 — McMap. All rights reserved.