3

I have never worked before with JSON data. I'm trying to deserialize the following line:

{"Mails":[null,{"ID":"[email protected]","Status":true},{"ID":"[email protected]","Status":false}]}

I'm using the following code but it's not working:

public Boolean checkValidLicense(string usermail)
{
    Boolean validUser = false;

    HttpWebRequest req = WebRequest.Create("https://popping-heat-1908.firebaseio.com/.json") as HttpWebRequest;
    using (HttpWebResponse resp = req.GetResponse() as HttpWebResponse)
    {

        StreamReader reader = new StreamReader(resp.GetResponseStream());
        string json = reader.ReadToEnd();

        dynamic result = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

        foreach (var item in result.Mails)
        {
            if (usermail == item.ID && item.Status == "true") 
            {
                validUser = true;
                break;
             }

        }

        return validUser;
    }

I'm getting:

'Newtonsoft.Json.Linq.JValue' does not contain a definition for 'ID'.

1
  • 1
    Could you create a typed model and use the generic (<T>) API? Commented Feb 13, 2015 at 14:37

3 Answers 3

2

Do not deserialize to dynamic type unless you have a strong reason to do so. Instead, create a type to deserialize to. A great tool for that is json2csharp, though you may often need to make minor adjustments for things it can't infer. Below, we've made two classes. Mail represents the individual items, and MailCollection is the root JSON object we're deserializing from, which simply contains a collection of Mail objects.

public class Mail
{
    public string ID { get; set; }
    public bool Status { get; set; }
}

//This is the root object, it's going to hold a collection of the mail
public class MailCollection
{
    public List<Mail> Mails { get; set; }
}

//we pass a type parameter telling it what type to deserialize to
MailCollection result = Newtonsoft.Json.JsonConvert.DeserializeObject<MailCollection>(json);
foreach (var item in result.Mails)
{
    if (usermail == item.ID && item.Status) //since item.Status is a bool, don't compare to a string.
    {
        validUser = true;
        break;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

There's an incredibly useful tool that not many know of directly included in Visual Studio itself! Copy the JSON in the clipboard, then go to a C# code file, then Edit -> Paste special -> Paste JSON as classes. Works really well most of the time and can do the same with XML, adding attributes for serialization and all.
@Gimly I don't have VS fired up right now. What version does that require, and does it require any special tools such as Mads Kristensen's Web Extensions?
Not sure about which version started this, but at least it is present in 2012 onward. And it's built-in, no special tools, directly in bare VS.
1

The problem is that the first value of the response you are getting is null. This is the result you are getting from the request:

{
  "Mails": [
    null,
    {
      "ID": "[email protected]",
      "Status": true
    },
    {
      "ID": "[email protected]",
      "Status": false
    }
  ]
}

So change the line:

if (usermail == item.ID && item.Status == "true") 

To the line:

if (item.Value != null && usermail == item.ID && item.Status == "true")

3 Comments

How does this solve the issue the OP has? You´re simply copying the response that he already posted.
Do you know how to remove the null element from the beggining?
Is it a one off or is all your json in that format? @Aldridge1991
-2
  1. You need to represent an object for the JSON to comprehend.

Usings

    using System.IO;
    using Newtonsoft.Json;

Object

    [JsonObject]
    public class MailItem
    {
        public int ID { get; set; }
        public Boolean Status { get; set; }

        [JsonIgnore]
        public String SomethingToNotInclude { get; set; }
    }

Get

  1. Build a json class to interact with creating, adding, editing and removing. First we need to Deserialize the json into List<MailItems>:

    private String path = "pathTo.json";
    public List<MailItem> GetMailItems()
    {
        if (!File.Exists(path))
            File.WriteAllText(path, "[]"); //returns an empty list
    
        String json = File.ReadAllText(path);
        return JsonConvert.DeserializeObject<List<MailItem>>(json);
    }
    

Add

  1. When Serializing, I get a full list of the json, then add the object MailItems to List, then serialize the list into json and finally write the json to a file.

    public void AddMailItem(MailItem mailItem)
    {
        String json = File.ReadAllText(fullPath);
        List<MailItem> mailItemList = JsonConvert.DeserializeObject<List<MailItem>>(json);
            if (mailItemList == null)
                mailItemList = new List<MailItem>();
        mailItemList.Add(mailItem);
        String json = JsonConvert.SerializeObject(mailItemList, Formatting.Indented);
        File.WriteAllText(json);
    }
    

Edit

  1. When updating an existing item:

    public void EditMailItem(MailItem mailItem)
    {
        String jsonRead = File.ReadAllText(fullPath);
        List<MailItem> mailItemList = JsonConvert.DeserializeObject<List<MailItem>>(jsonRead);
        int indexOfMailItem = mailItemList.FindIndex(o => o.ID == mailItem.ID); //LINQ
        mailItemList[indexOfMailItem] = mailItem;
        String jsonWrite = JsonConvert.SerializeObject(mailItemList, Formatting.Indented);
        File.WriteAllText(jsonWrite);
    }
    

1 Comment

List<Mails> mailsList = JsonConvert.DeserializeObject<List<Log>>(json); What is Log? Why is Mails plural when it only represents one Mail object? Why are you deserializing a JSON object into a C# collection?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.