如何在 dotnet 核心中将字典类型反序列化为 json

How to deserialize dictionary types to json in dotnet core

我正在与 SendGrid 的 API 进行一些集成,特别是围绕电子邮件中的搜索功能。

API 响应如下:

{
   "result":{
      "personsemail@domain.com":{
         "contact":{
            "address_line_1":"",
            "address_line_2":"",
            "alternate_emails":[
               
            ],
            "city":"",
            "country":"",
            "email":"personsemail@domain.com",
            "first_name":"Bob",
            "id":"111111-1111-1111-1111-111111111111",
            ...
         }
      },
      "anotheremail@domain.com":{
         "contact":{
            "address_line_1":"",
            "address_line_2":"",
            "alternate_emails":[
               
            ],
            "city":"",
            "country":"",
            "email":"anotheremail@domain.com",
            "first_name":"Alice",
            "id":"111112-1112-1112-1112-111111111112",
            ...
         }
      }
      ...
   }
}

有谁知道我如何适当地反序列化它,以便我可以像 iterate/search 的普通列表一样使用它?我希望我可以使用这样的东西:

var recipients = (await searchResponse.Content.ReadFromJsonAsync<**my-poco**>());

这与我用于所有其他调用的类似 - 但我不确定如何创建允许简单反序列化的 POCO。我很高兴忽略顶级 personsemail@domain.com 条目,只使用 linq..

搜索结果

如有任何建议,我们将不胜感激!

一种方法是使用 visual studio 将 api 响应粘贴为 class。你可以点击Edit -> Paste special -> Paste JSON as Classes。 这样做你会得到这些 classes:

public class EmailModel
{
    public Result result { get; set; }
}

public class Result
{
    public PersonsemailDomainCom personsemaildomaincom { get; set; }
}

public class PersonsemailDomainCom
{
    public Contact contact { get; set; }
}

public class Contact
{
    public string address_line_1 { get; set; }
    public string address_line_2 { get; set; }
    public object[] alternate_emails { get; set; }
    public string city { get; set; }
    public string country { get; set; }
    public string email { get; set; }
    public string first_name { get; set; }
    public string id { get; set; }
}
public class Contact
    {
        public Contact2 contact { get; set; }
    }

    public class Contact2
    {
        public string city { get; set; } ..other props
    }

string a = @"{
            ""personsemail @domain.com"":{
                ""contact"":{
                    ""city"":""""
                    }
            },
        ""personsemail @domain.com2"":{
                ""contact"":{
                    ""city"":""""
                }
            }
        }";

            var ddd = JsonConvert.DeserializeObject<Dictionary<string, Contact>>(a);

您可以将 json 映射到以下数据模型:

public class Response
{
    public Dictionary<string, Contact> Results { get; set; }
}
public class Contact
{
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public List<string> AlternateEmails { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string Id { get; set; }
}

根据您选择的序列化库(System.Text.Json 或 Json.NET),您应该使用 JsonPropertyNameAttribute or JsonPropertyAttribute

来注释属性

然后您可以使用 Response 类型参数调用 ReadFromJsonAsync


由于 e-mail 地址以冗余方式存储,您应该能够将 Dictionary<string, Contact> 转换为 List<Contact> collection

public class Response
{
    public Dictionary<string, Contact> Results { get; set; }
    public List<Contact> Contacts => Results.Values.ToList();
}

我最终使用以下 class 完成了这项工作。这是彼得回答的变体:

public class SendGridContactSearchResponse
{
    [JsonProperty("result", NullValueHandling = NullValueHandling.Ignore)]
    //public Result Result { get; set; }
    public Dictionary<string, Contact> result { get; set; }
}

public partial class Contact
{
    [JsonProperty("contact", NullValueHandling = NullValueHandling.Ignore)]
    public contact contact { get; set; }
}

public partial class contact
{
    [JsonProperty("address_line_1", NullValueHandling = NullValueHandling.Ignore)]
    public string AddressLine1 { get; set; }

    [JsonProperty("address_line_2", NullValueHandling = NullValueHandling.Ignore)]
    public string AddressLine2 { get; set; }

    [JsonProperty("alternate_emails", NullValueHandling = NullValueHandling.Ignore)]
    public List<object> AlternateEmails { get; set; }

    [JsonProperty("city", NullValueHandling = NullValueHandling.Ignore)]
    public string City { get; set; }

    [JsonProperty("country", NullValueHandling = NullValueHandling.Ignore)]
    public string Country { get; set; }

    [JsonProperty("email", NullValueHandling = NullValueHandling.Ignore)]
    public string Email { get; set; }

    [JsonProperty("first_name", NullValueHandling = NullValueHandling.Ignore)]
    public string FirstName { get; set; }

    [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)]
    public Guid? Id { get; set; }

    [JsonProperty("last_name", NullValueHandling = NullValueHandling.Ignore)]
    public string LastName { get; set; }

    [JsonProperty("list_ids", NullValueHandling = NullValueHandling.Ignore)]
    public List<object> ListIds { get; set; }

    [JsonProperty("segment_ids", NullValueHandling = NullValueHandling.Ignore)]
    public List<object> SegmentIds { get; set; }

    [JsonProperty("postal_code", NullValueHandling = NullValueHandling.Ignore)]
    public string PostalCode { get; set; }

    [JsonProperty("state_province_region", NullValueHandling = NullValueHandling.Ignore)]
    public string StateProvinceRegion { get; set; }

    [JsonProperty("phone_number", NullValueHandling = NullValueHandling.Ignore)]
    public string PhoneNumber { get; set; }

    [JsonProperty("whatsapp", NullValueHandling = NullValueHandling.Ignore)]
    public string Whatsapp { get; set; }

    [JsonProperty("line", NullValueHandling = NullValueHandling.Ignore)]
    public string Line { get; set; }

    [JsonProperty("facebook", NullValueHandling = NullValueHandling.Ignore)]
    public string Facebook { get; set; }

    [JsonProperty("unique_name", NullValueHandling = NullValueHandling.Ignore)]
    public string UniqueName { get; set; }

    [JsonProperty("custom_fields", NullValueHandling = NullValueHandling.Ignore)]
    public CustomFields CustomFields { get; set; }

    [JsonProperty("created_at", NullValueHandling = NullValueHandling.Ignore)]
    public DateTimeOffset? CreatedAt { get; set; }

    [JsonProperty("updated_at", NullValueHandling = NullValueHandling.Ignore)]
    public DateTimeOffset? UpdatedAt { get; set; }

    [JsonProperty("_metadata", NullValueHandling = NullValueHandling.Ignore)]
    public Metadata Metadata { get; set; }
}

修复是在 SendGridContactSearchResponse class 引用字典中的联系人 class 中。调用是这样的:

var searchResponse = JsonConvert.DeserializeObject<SendGridContactSearchResponse>(json);

反序列化工作正常!