locked
How to read all inner data from JSON string in C# RRS feed

  • Question

  • User1644346333 posted

    Hello,

    I am calling one JSON API and error response of their JSON API is not in any fixed structure. It returns error based on the field or type of error generated. there can be number of error response based on different case. Hence I cannot define proper class object for the error. But still I want to read through all the inner text from error response and show user a readable error message.

    I am sharing just 2 different error case response :

    case 1 error :

    {"client":{"phone":[{"message":"This field may not be null.","code":"null"}],"country":[{"message":"Object with code=US does not exist.","code":"does_not_exist"}]}}
     

    case 2 error :

    {"__all__":[{"message":"Malformed authorization header","code":"authentication_failed"}]}

    Please help me that how can I read all inner text here from JSON error response :

    Thanks

    Kusum

    Sunday, March 17, 2019 8:08 PM

Answers

  • User303363814 posted

    Install the Newtonsoft.Json package using NuGet https://www.nuget.org/packages/Newtonsoft.Json/

    Try this sample method.

    string FormatMessage(string errMsg)
    {
       var prop = Newtonsoft.Json.Linq.JObject.Parse(errMsg).First as JProperty;
       var childCount = (prop.Value as JToken).Children().Count();
       var separator = childCount == 1 ? string.Empty : ":";
       return $"{prop.Name}{separator} {DrillToMessage(prop.Value)}";
    }
    
    string DrillToMessage(JToken item)
    {
       string result = string.Empty;
       if (item is JArray)
       {
          foreach (var element in (item as JArray))
          {
             var details = element as JObject;
             var code = details["code"];
             var message = details["message"];
             result = $"=> code: {code}, message: {message}";
          }
       }
       else
       {
          var count = 1;
          foreach (var element in item)
          {
             if (element is JProperty) {
                var prop = element as JProperty;
                result +=  $"{count++}. {prop.Name} {DrillToMessage(prop.Value)}";
             } else {
                result += DrillToMessage(element);
             }
          }
       }
    	
       return result;
    }

    Call FormatMessage with your input string and the result should be a formatted messaged.

    Good luck

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, March 18, 2019 5:11 AM

All replies

  • User303363814 posted

    Suppose someone wrote you a method which took a single input parameter which was a string and which returned a result.

    What would you want the result to be if the input was 

    {"client":{"phone":[{"message":"This field may not be null.","code":"null"}],"country":[{"message":"Object with code=US does not exist.","code":"does_not_exist"}]}}

    What would you want the result to be if the input was 

    {"__all__":[{"message":"Malformed authorization header","code":"authentication_failed"}]}

    Unless we know what answer you want we cannot tell you how to get that answer

    Monday, March 18, 2019 12:00 AM
  • User1644346333 posted

    Hello Paul,

    {"client":{"phone":[{"message":"This field may not be null.","code":"null"}],"country":[{"message":"Object with code=US does not exist.","code":"does_not_exist"}]}}

    In this case, I want the output as " client :  1.  phone => code : null , message : This field may not be null. 2. country => code : does_not_exist, message :   Object with code=US does not exist.

    And for below

    {"__all__":[{"message":"Malformed authorization header","code":"authentication_failed"}]}

    I want the output like this :

    __all__ => code : authentication_failed, message :Malformed authorization header.

    Monday, March 18, 2019 2:35 AM
  • User36583972 posted

    Hello Paul,

    {"client":{"phone":[{"message":"This field may not be null.","code":"null"}],"country":[{"message":"Object with code=US does not exist.","code":"does_not_exist"}]}}

    In this case, I want the output as " client :  1.  phone => code : null , message : This field may not be null. 2. country => code : does_not_exist, message :   Object with code=US does not exist.

    And for below

    {"__all__":[{"message":"Malformed authorization header","code":"authentication_failed"}]}

    I want the output like this :

    __all__ => code : authentication_failed, message :Malformed authorization header.

    Please refer the following article. Using JSON.NET for dynamic JSON parsing and Stitch the string format you want to output. Please make a test on your side.

    Using JSON.NET for dynamic JSON parsing
    https://weblog.west-wind.com/posts/2012/aug/30/using-jsonnet-for-dynamic-json-parsing

    Best Regards

    Yong Lu

    Monday, March 18, 2019 3:58 AM
  • User303363814 posted

    Install the Newtonsoft.Json package using NuGet https://www.nuget.org/packages/Newtonsoft.Json/

    Try this sample method.

    string FormatMessage(string errMsg)
    {
       var prop = Newtonsoft.Json.Linq.JObject.Parse(errMsg).First as JProperty;
       var childCount = (prop.Value as JToken).Children().Count();
       var separator = childCount == 1 ? string.Empty : ":";
       return $"{prop.Name}{separator} {DrillToMessage(prop.Value)}";
    }
    
    string DrillToMessage(JToken item)
    {
       string result = string.Empty;
       if (item is JArray)
       {
          foreach (var element in (item as JArray))
          {
             var details = element as JObject;
             var code = details["code"];
             var message = details["message"];
             result = $"=> code: {code}, message: {message}";
          }
       }
       else
       {
          var count = 1;
          foreach (var element in item)
          {
             if (element is JProperty) {
                var prop = element as JProperty;
                result +=  $"{count++}. {prop.Name} {DrillToMessage(prop.Value)}";
             } else {
                result += DrillToMessage(element);
             }
          }
       }
    	
       return result;
    }

    Call FormatMessage with your input string and the result should be a formatted messaged.

    Good luck

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, March 18, 2019 5:11 AM
  • User1644346333 posted

    Thanks a lot Paul. It is giving result as expected.

    Monday, March 18, 2019 5:14 AM