【问题标题】:C# deserialize json and findC#反序列化json并查找
【发布时间】:2019-09-18 11:56:27
【问题描述】:

如何在此列表中找到特定的 id?

var contactList = JsonConvert.DeserializeObject<ContactList>(jsonString);

contactList.contacts.FindAll(x => x.id == item.id);

上面的代码没有按 id 过滤,而是从对象返回所有行。

(Visual Studio 没有向我显示 .Where 子句仅 .Find 和 .FindAll)

C#代码

namespace RestDemo.Model 
{ 
   public class Phone 
   { 
      public string mobile { get; set; } 
      public string home { get; set; } 
      public string office { get; set; } 
   } 

   public class Contact 
   { 
      public int id { get; set; } 
      public string name { get; set; } 
      public string email { get; set; } 
      public string address { get; set; } 
      public string gender { get; set; } 
      public Phone phone { get; set; } 
   } 

   public class ContactList 
   { 
      public List<Contact> contacts { get; set; } 
   } 
}

json:

{ "contacts": [     {           "id": 200,          "name": "Ravi Tamada",          "email": "ravi@gmail.com",          "address": "xx-xx-xxxx,x - street, x - country",            "gender": "male",           "phone": {              "mobile": "+91 0000000000",             "home": "00 000000",                "office": "00 000000"           }       },      {           "id": 201,          "name": "Klev Krist",           "email": "klev@gmail.com",          "address": "xx-xx-xxxx,x - street, x - country",            "gender": "male",           "phone": {              "mobile": "+91 0000000000",             "home": "00 000000",                "office": "00 000000"           }       },      {           "id": 202,          "name": "Paul Neil",            "email": "paul.neil@gmail.com",         "address": "xx-xx-xxxx,x - street, x - country",            "gender": "male",           "phone": {              "mobile": "+91 0000000000",             "home": "00 000000",                "office": "00 000000"           }       }   ]}

谢谢

【问题讨论】:

  • 你的 jsonString 长什么样子?
  • 告诉我们ContactList类,contactsjsonString中有什么
  • 您不会在任何地方分配FindAll 的结果。你怎么知道过滤不起作用?
  • FindAll 不是“就地”的东西。它返回过滤后的列表。存放在某处

标签: c# json linq object json-deserialization


【解决方案1】:

FindAll 方法不会将对象分配给搜索结果。

您必须将搜索结果保存在某处。

多结果示例

如果您期待多个结果

var contactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
var findedContact = contactList.contacts.FindAll(x => x.id == item.id);
//You business codes..

单个结果示例

如果您只等待 1 个结果

var contactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
var oneContact = contactList.contacts.Find(x => x.id == item.id);
if(oneContact ==null){
    //not found business codes
}
else {
   //find result business codes
}

【讨论】:

  • .Find() 不适用于 1 个结果。它带来了几行。我将改用 Linq。谢谢。
  • @user2250504 不强制使用 linq。对于这种情况 Find(single) 或 FindAll(multi)。我在答案中说了两个答案。
  • 好的,在模拟测试中 Find() 或 Where() 工作成功。稍后我将尝试在官方代码中实现。谢谢。
【解决方案2】:

假设你想找到某个 id,我们会调用它

var idToFind = "myID";

要查找具有该 ID 的所有联系人:

var contacts = contactList.contacts.Where(contact=> contact.id == idToFind);

要找到至少一个具有该 ID 的联系人:

var contactWithID = contactList.contacts.FirstOrDefault(contact=> contact.id == idToFind);
// Before using, check if null, means no contact matched the id.
if(contactWithID != null)
{
   // A contact was found.
}
else
{
   // No contact matching that id is found.
}

【讨论】:

  • Visual Studio 没有显示 .Where Claude only .Find 或 .FindAll
  • @user2250504 在编写FirstOrDefaultWhere 时遇到什么错误
  • @user2250504 在类文件的顶部使用 System.Linq 添加。
  • 好的,我试试。谢谢!
【解决方案3】:

针对您的情况,我使用相同的 Model 结构来反序列化您的 JSON,然后使用 Where linq 子句来实现您的要求。可以在以下位置找到工作小提琴:https://dotnetfiddle.net/SAcFja

代码:

using System;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        var jsonString = @"{ 'contacts': [{ 'id': 200, 'name': 'Ravi Tamada', 'email': 'ravi@gmail.com', 'address': 'xx-xx-xxxx,x - street, x - country', 'gender': 'male', 'phone': { 'mobile': '+91 0000000000', 'home': '00 000000', 'office': '00 000000' } }] }";
        var data= JsonConvert.DeserializeObject<ContactList>(jsonString);
        //Console.WriteLine(data.contacts);

        var found=data.contacts.Where(x=>x.id.ToString()=="200");

        foreach(var value in found)
        {
          Console.WriteLine(value.id);
          Console.WriteLine(value.address);     
        }       
    }
}

   public class Phone 
   { 
      public string mobile { get; set; } 
      public string home { get; set; } 
      public string office { get; set; } 
   } 

   public class Contact 
   { 
      public string id { get; set; } 
      public string name { get; set; } 
      public string email { get; set; } 
      public string address { get; set; } 
      public string gender { get; set; } 
      public Phone phone { get; set; } 
   } 

   public class ContactList 
   { 
      public List<Contact> contacts { get; set; } 
   }

id=200 时的输出:

200
xx-xx-xxxx,x - street, x - country

【讨论】:

  • Visual Studio 没有显示 .Where() 子句来过滤对象内容...只有 .Find() 或 .FindAll()
  • @user2250504 你必须在你的项目中导入System.Linq
  • 好的,我会试试的。谢谢。
  • @user2250504 你的框架版本是多少?您可以通过转到项目 -> 属性 -> 应用程序并检查目标框架属性来检查。如果您的目标框架早于 3.5,那么 System.Linq 将无法工作,因为它是在 .NET Framework 3.5 上引入的。可以在此处找到有关此主题的更多信息:stackoverflow.com/questions/24659934/…
  • 版本 4.7 感谢
【解决方案4】:

根据您对@Tenretni 答案的评论,我猜您错过了在代码中使用System.Linq 库。

在您的代码中导入System.Collections.GenericSystem.Linq 并使用FirstOrDefault().Where() 子句

using System.Collections.Generic;
using System.Linq;

//…

string jsonString = @"{ 'contacts': [{ 'id': 'c200', 'name': 'Ravi Tamada', 'email': 'ravi@gmail.com', 'address': 'xx-xx-xxxx,x - street, x - country', 'gender': 'male', 'phone': { 'mobile': '+91 0000000000', 'home': '00 000000', 'office': '00 000000' } }] }";

var contactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
var item = "c200";
var result = contactList.contacts.FirstOrDefault(x => x.id == item);
Console.WriteLine(result.name);

//If you have multiple records with same ID then you can try where clause
var result = contactList.contacts.Where(x => x.id == item);      //Here result will be list of Contact

.Net Fiddle

【讨论】:

  • 这种情况下,通过id搜索可以找到多于1行。我可以列出很多行,但不想列出所有行.....
  • @user2250504 在这种情况下,您可以使用 .Where() 子句。
  • 是的,但我会添加 System.Linq 参考...它不见了。谢谢。
猜你喜欢
  • 2012-08-26
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多