0

Hi I'm trying to parse a JSON page in C#, but I can't seem to read some strings, like:

"versions": [
    {
        "date": 1340466559, 
        "dl_link": "http://dev.bukkit.org/media/files/599/534/NoSwear.jar", 
        "filename": "NoSwear.jar", 
        "game_builds": [
            "CB 1.2.5-R4.0"
        ], 
        "hard_dependencies": [], 
        "md5": "d0ce03e817ede87a9f76f7dfa67a64cb", 
        "name": "NoSwear v5.1", 
        "soft_dependencies": [], 
        "status": "Semi-normal", 
        "type": "Release"
    }, 

How could I read that? This is the code I have right now and works for everything else except this:

public static void GetMoreInfo(string plugin)
{
    try
    {
        string url = "http://bukget.org/api/plugin/";

        var wc = new WebClient();
        var json = wc.DownloadString(url + plugin);
        var moreInfo = JsonConvert.DeserializeObject<MoreInfo>(json);

        foreach (var category in moreInfo.categories)
        {
            Categories += category + ", ";
        }
        Categories = Categories.Remove(Categories.Length - 2, 2);
    }
    catch (Exception)
    {

    }
    finally
    {
        if (string.IsNullOrEmpty(Categories))
        {
            Categories = "No data found.";
        }
    }
}

public class MoreInfo
{
    public string[] categories;
}
3
  • 4
    What do you mean by 'can't seem to read strings'? I see you're swallowing all exceptions so you'll never know if anything is thrown that might give you a clue. What happens if you comment out the try? Commented Jul 16, 2012 at 18:37
  • 1
    Also, are you trying to parse the posted JSON into an instance of MoreInfo? In that case, I'd imagine the class definition of MoreInfo needs to match the JSON and not just have a string[] field. Commented Jul 16, 2012 at 18:39
  • This is the exception I get: Error reading string. Unexpected token: StartArray. Path 'versions', line 13, position 18. after I added public string versions; to the class MoreInfo Commented Jul 16, 2012 at 18:45

2 Answers 2

4

How about handling your json dynamically, instead of deserializing to a concrete class?

var wc = new WebClient();
var json = wc.DownloadString("http://bukget.org/api/plugin/test");

dynamic moreInfo = JsonConvert.DeserializeObject(json);

Console.WriteLine("{0} {1} {2}", moreInfo.name, moreInfo.desc, moreInfo.status);
string categories = String.Join(",", moreInfo.categories);
Console.WriteLine(categories);

Or would you prefer the classical approach?

var plugin = JsonConvert.DeserializeObject<Plugin>(json);
string categories = String.Join(",",plugin.categories);

public class Plugin
{
    public List<string> authors;
    public string bukkitdev_link;
    public List<string> categories;
    public string desc;
    public string name;
    public string plugin_name;
    public string status;
    public List<Version> versions;
}

public class Version
{
    public string date;
    public string filename;
    public string name;
    //.......
}
Sign up to request clarification or add additional context in comments.

3 Comments

:o looks and works great! But c# returns null for anytyhing that is in "versions". Any idea?
@Darkshadw Can you post a full-json or and url?
@Darkshadw above code works, just tested. Have you renamed something?
0

I could be wrong, but the JSON you're receiving is an array named versions but you're trying to deserialize it into a MoreInfo object that exposes an array named categories (unless it's just a typo in your example). Have you tried renaming MoreInfo.categories to MoreInfo.versions?

UPDATE

I don't think that would make a difference because the JSON converter doesn't know what to do with each object in the array. You need to provide an object to deserialize each element in the JSON array.

For example, try modifying the MoreInfo object to include matching properties to the JSON string (the elements in the array)

[DataContract]
public class MoreInfo
{
  [DataMember]
  public DateTime date { get; set; }

  [DataMember]
  public string dl_link { get; set; }
  ...
}

And then try to deserialize the JSON string to a List<MoreInfo>:

JsonConverter.DeserializeObject<List<MoreInfo>>(json)

You will then have to modify the rest of your code to work with MoreInfo objects and not strings in an array.

REFER TO THIS ANSWER

See this question, the accepted answer should help you solve your problem: Json.NET: Deserialization with list of objects

6 Comments

Figured. I think you need to do a JsonConverter.DeserializeObject<List<MoreInfo>>(json) and modify MoreInfo to include the appropriate properties.
Do you have any tips on how to do this? I'm pretty new with JSON :(. Because now it's become a list :o.
Updated my answer. The JSON you're receiving represents a list of objects so it makes sense for the JsonConverter to deserialize to a List<T> where T is an object you define with matching properties, i.e., same names as those found in the JSON string.
When I do all of that, c# is still complaining: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from ...
I think you're getting that error because it's a named array, i.e., "versions: [...]" as opposed to just "[]". Are you in control of the JSON response? Can you remove the "versions" preceding the array?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.