9

I have a json string that was created from serializing an array of objects :

[
    {
        "html": "foo"
    },
    {
        "html": "bar"
    }
]

How can I deserialize it to some iterable C# structure ? I've tried this code, but I'm getting No parameterless constructor defined for type of 'System.String'. error :

string[] htmlArr = new JavaScriptSerializer().Deserialize<String[]>(html);

What I want to receive is an iterable structure to get each 'html' object.

mike_hornbeck
  • 1,612
  • 3
  • 30
  • 51
  • 2
    Checkout this previous stackoverflow post, http://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object or http://stackoverflow.com/questions/7895105/json-deserialize-c-sharp – MethodMan Dec 30 '12 at 23:09
  • thanks for the links, I was first trying to do this without creating an additional class but I can leave with it I guess :) – mike_hornbeck Dec 30 '12 at 23:23
  • possible duplicate of [Parsing json objects](http://stackoverflow.com/questions/10432647/parsing-json-objects) – nawfal Jul 15 '14 at 08:48

4 Answers4

11

Use a class for each JSON object. Example:

public class HtmlItem
{
   [DataMember(Name = "html")]
   public string Html { get; set; }
}

JavaScriptSerializer ser = new JavaScriptSerializer();          

// Serialize
string html = ser.Serialize(new List<HtmlItem> {
   new HtmlItem {  Html = "foo" },
   new HtmlItem {  Html = "bar" }
});

// Deserialize and print the html items.        
List<HtmlItem> htmlList = ser.Deserialize<List<HtmlItem>>(html);
htmlList.ForEach((item) => Console.WriteLine(item.Html)); // foo bar
nekman
  • 1,919
  • 2
  • 15
  • 26
  • I accept your answer as I've finally used something similar from the link in the question comments. What is this `DataMember` decorator added for ? – mike_hornbeck Dec 30 '12 at 23:24
  • Thanks! I think that the name in the DataMember attribute is used to mapp your JSON-property to your instance property. Read more about the `DataMember`[here](http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.aspx) – nekman Dec 30 '12 at 23:31
4

You can use Newtonsoft Json.NET (available from NuGet)

string json = @"[{""html"": ""foo""},{""html"": ""bar""}]";
var items = JsonConvert.DeserializeObject<List<Item>>(json);

Where

public class Item
{
    public string Html { get; set; }
}
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
2

The docs site apparently isn't working right now... But I would try using JSON.NET ( http://james.newtonking.com/projects/json/help/ )

There are a couple of ways you can do it. You can deserialize in a very dynamic not type strict way or you can define an object that matches the json object exactly and deserialize into that. If there are many formats of JSON you'll have to serialize I would recommend using schemas.

evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115
1

Answer of nekman is not completely correct, the attribute should be JsonPropery instead of DataMember. (in this case you can remove the attribute since the deserializer doesn't care about the capital H)

public class HtmlItem
{
   [JsonProperty("html")]
   public string Html { get; set; }
}

JavaScriptSerializer ser = new JavaScriptSerializer();          

// Serialize
string html = ser.Serialize(new List<HtmlItem> {
   new HtmlItem {  Html = "foo" },
   new HtmlItem {  Html = "bar" }
});

// Deserialize and print the html items.        
List<HtmlItem> htmlList = ser.Deserialize<List<HtmlItem>>(html);
htmlList.ForEach((item) => Console.WriteLine(item.Html)); // foo bar
L01NL
  • 1,753
  • 1
  • 13
  • 17