Asphaug
Asphaug

Reputation: 21

Parse json from web request response

Im trying to parse a http web response into an array or something so i can work with the information. This is the json response i get (+ a lot more, but i just censored the format):

{
    "meta": {
        "status": 200
    },
    "data": {
        "account": {
            "account_phone_number": "XXXXXXXX",
            "account_email": "[email protected]"
        },
        "user": {
            "id": "5f2b17e7836fc7010025aed3",
            "age": 23,
        }
    }
}

How can i write the "id" inside of "user" to console or a textbox?

This is my web request:

private void button1_Click(object sender, EventArgs e)
{
    const string WEBSERVICE_URL = "url_here";
    try
    {
        var webRequest = System.Net.WebRequest.Create(WEBSERVICE_URL);
        if (webRequest != null)
        {
            webRequest.Method = "GET";
            webRequest.Timeout = 12000;
            webRequest.ContentType = "application/json";
            webRequest.Headers.Add("x-auth-token", "Auth_token");

            using (System.IO.Stream s = webRequest.GetResponse().GetResponseStream())
            {
                using (System.IO.StreamReader sr = new System.IO.StreamReader(s))
                {
                    var jsonResponse = sr.ReadToEnd();
                    richTextBox1.AppendText(jsonResponse);
                }
            }
        }
    }
    catch (Exception ex)
    {
        richTextBox1.AppendText("No workie");
    }
}

I have tried the following:

public class Test
{
   public string meta {get;set;}
   public string data {get;set;}
}

and trying to serialize the json into a table as following:

JavaScriptSerializer js = new JavaScriptSerializer();
Test[] Tester = js.Deserialize<Test[]>(jsonResponse);
richTextBox1.AppendText(Tester);

But no luck. Can anyone please point me in the right direction here?

Upvotes: 0

Views: 1177

Answers (2)

Peter Csala
Peter Csala

Reputation: 22714

If you are able to use other serializer than JavaScriptSerializer then you can take advantage of partial deserializing.

In case of Json.NET (formerly known as Newtonsoft Json) you have at least two options:

SelectToken

JObject semiParsedData = JObject.Parse(jsonResponse);
string id = (string)semiParsedData.SelectToken("data.user.id");
int age = (int)semiaParsedData.SelectToken("data.user.age");
string email = (string)semiParsedData.SelectToken("data.account.account_email");
  • By calling the Parse method we will have a semi-parsed object.
  • On this object we can issue a Json Path query via the SelectToken.
    • The syntax is similar to XPath, which can be used to retrieve any arbitrary data form an XML.
    • More precisely it is a JPath.
  • SelectToken returns a JToken. From it you can retrieve data in several ways:
    • (string)semiParsedData.SelectToken("data.user.id")
    • semiParsedData.SelectToken("data.user.id").Value<string>()
    • semiParsedData.SelectToken("data.user.id").ToObject<string>()

References:

indexer operator

JObject semiParsedData = JObject.Parse(jsonResponse);
JToken data = semiParsedData["data"];

JToken user = data["user"];
string id = (string)user["id"];
int age = (int)user["age"];

JToken account = data["account"];
string email = (string)account["account_email"];
  • JToken defines the following indexer operator, which is not really useful:
public virtual JToken? this[object key]
{
    get => throw new InvalidOperationException("Cannot access child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
    set => throw new InvalidOperationException("Cannot set child value on {0}.".FormatWith(CultureInfo.InvariantCulture, GetType()));
}
  • On the other hand its derived class JObject overrides this to make that functionality useful:
    • (JObject derives from JContainer, which derives from JToken).
public JToken? this[string propertyName]
{
    get
    {
        ValidationUtils.ArgumentNotNull(propertyName, nameof(propertyName));
        JProperty? property = Property(propertyName, StringComparison.Ordinal);
        return property?.Value;
    }
    set
    {
        JProperty? property = Property(propertyName, StringComparison.Ordinal);
        if (property != null)
        {
            property.Value = value!;
        }
        else
        {
#if HAVE_INOTIFY_PROPERTY_CHANGING
            OnPropertyChanging(propertyName);
#endif
            Add(propertyName, value);
            OnPropertyChanged(propertyName);
        }
    }
}
  • Here the Property method tries to get the requested entity from the _properties collection:
    • private readonly JPropertyKeyedCollection _properties

Reference:

Upvotes: 1

Muhammad Usama Alam
Muhammad Usama Alam

Reputation: 209

Everything is Correct except your Test Class

For Complex JSON use https://json2csharp.com/ For Converting Json To C# Class

public class Meta    {
    public int status { get; set; } 
}

public class Account    {
    public string account_phone_number { get; set; } 
    public string account_email { get; set; } 
}

public class User    {
    public string id { get; set; } 
    public int age { get; set; } 
}

public class Data    {
    public Account account { get; set; } 
    public User user { get; set; } 
}

public class Root    {
    public Meta meta { get; set; } 
    public Data data { get; set; } 
}

and Then Use This

JavaScriptSerializer js = new JavaScriptSerializer();
var Root = js.Deserialize<Root>(jsonResponse);

Upvotes: 0

Related Questions