C#中的JSON反序列化比较

3

我之前没有处理过JSON数据。我正在尝试将以下行反序列化:

{"Mails":[null,{"ID":"ulasdas@gmail.com","Status":true},{"ID":"ADSsdasA@ONO.COM","Status":false}]}

我使用了以下代码,但是它并没有起作用:

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;
    }

我遇到了以下问题:

'Newtonsoft.Json.Linq.JValue'没有定义 'ID'。


1
你能创建一个已定义类型的模型并使用泛型 (<T>) API 吗? - Marc Gravell
3个回答

2
不要使用dynamic类型进行反序列化,除非你有充分的理由这样做。相反,应该创建一个用于反序列化的类型。一个很好的工具是json2csharp,尽管你可能经常需要进行一些微小的调整以解决它无法推断的问题。下面我们创建了两个类。 Mail表示单个项目,MailCollection是我们将从中反序列化的根JSON对象,它简单地包含一组Mail对象。
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;
    }
}

2
在 Visual Studio 中有一个非常实用的工具,但很少有人知道它!将 JSON 复制到剪贴板中,然后转到 C# 代码文件,然后选择“编辑”->“特殊粘贴”->“将 JSON 粘贴为类”。大多数情况下都能很好地工作,并且也可以使用相同的方法处理 XML,添加序列化和所有属性。 - Gimly
@Gimly,我现在没有运行VS。那需要什么版本,以及是否需要像Mads Kristensen的Web扩展这样的特殊工具? - mason
不确定从哪个版本开始,但至少它存在于2012年及以后的版本中。而且它是内置的,没有特殊的工具,直接在裸的VS中使用。 - Gimly

1
问题在于你得到的响应的第一个值是null。这是你从请求中获取的结果:
{
  "Mails": [
    null,
    {
      "ID": "ulrickpspg@gmail.com",
      "Status": true
    },
    {
      "ID": "ADSA@ONO.COM",
      "Status": false
    }
  ]
}

所以更改该行:

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

到这一行:

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

这怎么解决OP的问题?你只是在复制他已经发布的回复。 - MakePeaceGreatAgain
你知道如何从开头删除空元素吗? - Aldridge1991
你的JSON数据是一次性的还是都是这种格式?@Aldridge1991 - Andrew Grinder

-2
你需要为 JSON 表示一个对象。
    using System.IO;
    using Newtonsoft.Json;

对象

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

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

获取

构建一个json类来进行创建、添加、编辑和删除的交互。首先,我们需要将json反序列化为List<MailItems>
private String path = "pathTo.json";
public List<MailItem> GetMailItems()
{
    if (!File.Exists(path))
        File.WriteAllText(path, "[]"); //返回一个空列表

    String json = File.ReadAllText(path);
    return JsonConvert.DeserializeObject<List<MailItem>>(json);
}

添加

  • 序列化时,我会得到一个完整的 JSON 列表,然后将对象 MailItems 添加到列表中,接着将列表序列化为 JSON,最后将 JSON 写入文件。

    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);
    }
    
  • 编辑

  • 更新现有项目时:

    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);
    }
    

  • List<Mails> mailsList = JsonConvert.DeserializeObject<List<Log>>(json); 中的 Log 是什么?为什么 Mails 是复数形式,而它只代表一个 Mail 对象?为什么要将 JSON 对象反序列化为 C# 集合? - mason

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接