How to use JSON.Net to read JSON and output HTML?

12,156

Solution 1

Here is how you can "walk around" your JObject to extract the information you need.

string json = @"
{
    ""photos"": {
        ""photo1"": {
            ""src"": ""/images/foo.jpg"",
            ""alt"": ""Hello World!""
        },
        ""photo2"": {
            ""src"": ""/images/bar.jpg"",
            ""alt"": ""Another Photo""
        }
    }
}";

StringBuilder sb = new StringBuilder();
JObject o = JObject.Parse(json);

foreach (JProperty prop in o["photos"].Children<JProperty>())
{
    JObject photo = (JObject)prop.Value;
    sb.AppendFormat("<img src='{0}' alt='{1}' />\r\n", 
                     photo["src"], photo["alt"]);
}

Console.WriteLine(sb.ToString());

Output:

<img src='/images/foo.jpg' alt='Hello World!' />
<img src='/images/bar.jpg' alt='Another Photo' />

Solution 2

First you need to define a class that holds your data and also is able to output itself as an HTML tag:

public class Photo
{
    public string Src { get; set; }
    public string Alt { get; set; }

    public string ToHtml()
    {
        return string.Format(
            "<img src='{0}' alt='{1}'/>,
            this.Src,
            this.Alt);
    }
}

In order to be able to use JSON.Net for creating typed objects, you need to 'normalize' your JSON - it is not entirely in the usual format that would indicate an array of identical objects. You have to entirely get rid of the identifiers photo*1*, photo*2*,.., photo*n*, or you have to make them identical (i.e. they all should simply be photo, without number). If you can control JSON creation, you can do it right there. Otherwise you must manipulate the web response accordingly (e.g. with string.Replace(...)).

Having done that, you can use JSON.Net to get a typed list, and subsequently you can simply iterate through it to get the required HTML:

var client = new WebClient();
client.Headers.Add("User-Agent", "Nobody");
string response = client.DownloadString(new Uri("http://www.example.com/photos.json"));
// --> 'Normalize' response string here, if necessary
List<Photo> photos = JsonConvert.DeserializeObject<List<Photo>>(response);

// now buid the HTML string
var sb = new StringBuilder();
foreach(photo in photos)
{
    sb.Append(photo.ToHtml());
}
string fullHtml = sb.ToString();
...
Share:
12,156
edt
Author by

edt

Updated on June 05, 2022

Comments

  • edt
    edt almost 2 years

    How can I use JSON.Net and loop through the following JSON to output one HTML image tag (a string) for each member of the "photos" object?

    My goal is to read the below JSON and output this string:

    "<img src='/images/foo.jpg' alt='Hello World!'><img src='/images/bar.jpg' alt='Another Photo' />"
    

    JSON is stored in external file "photos.json"

    {
        "photos": {
            "photo1": {
                "src": "/images/foo.jpg",
                "alt": "Hello World!"
            },
            "photo2": {
                "src": "/images/bar.jpg",
                "alt": "Another Photo"
            }
        }
    }
    

    I've started with code similar to what's shown here: http://www.hanselman.com/blog/NuGetPackageOfTheWeek4DeserializingJSONWithJsonNET.aspx

    var client = new WebClient();
    client.Headers.Add("User-Agent", "Nobody");
    var response = client.DownloadString(new Uri("http://www.example.com/photos.json"));
    JObject o = JObject.Parse(response);'
    //Now o is an object I can walk around...
    

    But, I haven't found a way to "walk around o" as shown in the example.

    I want to loop through each member of the photos object, read the properties and add html to my string for each photo.

    So far, I've tried the examples shown here: http://james.newtonking.com/json/help/index.html?topic=html/QueryJson.htm But, I cannot make them work once inside a for each loop.