dynamic c# ValueKind = Object

Viewed 30261

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"
}
7 Answers

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.

Found a real way to tackle it i have used JObject instead of dynamic. Here is a sample below.

public ResponseWrapper<GenericResponseModel> PostServiceStreams(JObject jObject)
{
  return ResponseService.ReturnResponse(() =>
  {
     return new GenericResponseModel(true, string.Empty,database.MarkedIssues.Select(j => j).ToList().Select(i => i.MapMarkedIssuesModels()).ToList());
  }, Request);
}

As you can get values like this below.

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

This is a object which i'm sending. Here is the receiving method.

jObject["OTP"].ToString();
public async Task<dynamic> PostAsync([FromBody] Object post)
{
     var data = JsonConvert.DeserializeObject<dynamic>(post.ToString());

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.

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") { } 
} 

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;

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);
}
Related