首页 > 解决方案 > 使用 ASP.NET Core 反序列化多维 JSON 数组

问题描述

我已经尝试了几天来找到这个问题,也许我错过了一些东西。

当我基于 GitHub 构建示例应用程序时,我遵循了 Microsoft 的建议: https ://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1

不幸的是,这段代码似乎不适用于多维数组。

我的应用程序希望从我们的 Teamwork Desk 帐户中获取信息,以便我们可以使用 ASP.NET 应用程序创建报告。

关于如何使这项工作发挥作用的任何提示或想法都会很棒。

这是我的代码:

文件夹 (Models.TeamworkDesk) | 客户.cs

using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Vanilla.Models.TeamworkDesk
{
    public class Contact
    {
        [JsonPropertyName("id")]
        public int Id { get; set; }

        [JsonPropertyName("value")]
        public string Value { get; set; }

        [JsonPropertyName("type")]
        public string Type { get; set; }

        [JsonPropertyName("isMain")]
        public bool IsMain { get; set; }

        [JsonPropertyName("createdAt")]
        public DateTime CreatedAt { get; set; }
    }

    public class Customer
    {
        [JsonPropertyName("id")]
        public int Id { get; set; }

        [JsonPropertyName("timezoneId")]
        public int TimezoneId { get; set; }

        [JsonPropertyName("avatarURL")]
        public string AvatarURL { get; set; }

        [JsonPropertyName("email")]
        public string Email { get; set; }

        [JsonPropertyName("contacts")]
        public List<Contact> Contacts { get; set; }

        [JsonPropertyName("externalId")]
        public string ExternalId { get; set; }

        [JsonPropertyName("extraData")]
        public string ExtraData { get; set; }

        [JsonPropertyName("firstName")]
        public string FirstName { get; set; }

        [JsonPropertyName("jobTitle")]
        public string JobTitle { get; set; }

        [JsonPropertyName("language")]
        public string Language { get; set; }

        [JsonPropertyName("lastName")]
        public string LastName { get; set; }

        [JsonPropertyName("address")]
        public string Address { get; set; }

        [JsonPropertyName("mobile")]
        public string Mobile { get; set; }

        [JsonPropertyName("notes")]
        public string Notes { get; set; }

        [JsonPropertyName("organization")]
        public string Organization { get; set; }

        [JsonPropertyName("phone")]
        public string Phone { get; set; }

        [JsonPropertyName("trusted")]
        public bool Trusted { get; set; }

        [JsonPropertyName("welcomeEmailSent")]
        public bool WelcomeEmailSent { get; set; }

        [JsonPropertyName("facebookURL")]
        public string FacebookURL { get; set; }

        [JsonPropertyName("googlePlusURL")]
        public string GooglePlusURL { get; set; }

        [JsonPropertyName("linkedinURL")]
        public string LinkedinURL { get; set; }

        [JsonPropertyName("twitterHandle")]
        public string TwitterHandle { get; set; }

        [JsonPropertyName("createdAt")]
        public DateTime CreatedAt { get; set; }

        [JsonPropertyName("createdBy_users_id")]
        public int CreatedBy_Users_Id { get; set; }

        [JsonPropertyName("updatedAt")]
        public DateTime UpdatedAt { get; set; }

        [JsonPropertyName("updatedBy_users_id")]
        public int UpdatedBy_Users_Id { get; set; }

        [JsonPropertyName("company")]
        public object Company { get; set; }

        [JsonPropertyName("lastTicketDate")]
        public DateTime? LastTicketDate { get; set; }

        [JsonPropertyName("numTickets")]
        public int NumTickets { get; set; }
    }

    public class RootObject
    {
        [JsonPropertyName("customers")]
        public List<RootObject> Customers { get; set; }

        [JsonPropertyName("totalCustomers")]
        public int TotalCustomers { get; set; }
    }
}

文件夹(页)| Teamwork.cshtml.cs

using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Vanilla.Models.TeamworkDesk;

namespace Vanilla.Pages
{
    public class TeamworkModel : PageModel
    {

        private readonly IHttpClientFactory _clientFactory;

        public IEnumerable<Customer> Customers { get; private set; }

        public bool GetCustomersError { get; private set; }

        public TeamworkModel(IHttpClientFactory clientFactory)
        {
            _clientFactory = clientFactory;
        }


        public async Task OnGet()
        {
            var request = new HttpRequestMessage(HttpMethod.Get,"https://vanillacompany.teamwork.com/desk/v1/customers.json");

            var client = _clientFactory.CreateClient();

            var byteArray = Encoding.ASCII.GetBytes("myUniqueKey:");
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));

            var response = await client.SendAsync(request);

            if (response.IsSuccessStatusCode)
            {
                using var responseStream = await response.Content.ReadAsStreamAsync();
                Customers = await JsonSerializer.DeserializeAsync<IEnumerable<Customer>>(responseStream);

            }
            else
            {
                GetCustomersError = true;
                Customers = Array.Empty<Customer>();
            }

        }
    }

}

文件夹(页)| 团队合作.cshtml

@page
@model Vanilla.Pages.TeamworkModel
@{
    ViewData["Title"] = "Teamwork Customers";
    Layout = "~/Pages/Shared/_Layout.cshtml";
}

@if (Model.GetCustomersError)
{
    <p>Unable to get customers from Teamwork. Please try again later.</p>
}
else
{
<ul>
    @foreach (var customer in Model.Customers)
    {
        <li>@customer.FirstName</li>
    }
</ul>

JSON 示例:

{
    "customers": [
        {
            "id": 94572,
            "timezoneId": 0,
            "avatarURL": "https://vanillacompany.teamwork.com/desk/images/examples/noPhoto1.png",
            "email": "testytester@vanillacompany.com",
            "contacts": [
                {
                    "id": 44783,
                    "value": "testytester@vanillacompany.com",
                    "type": "email",
                    "isMain": true,
                    "createdAt": "0001-01-01T00:00:00Z"
                }
            ],
            "externalId": "",
            "extraData": "",
            "firstName": "Testy",
            "jobTitle": "Code Tester",
            "language": "en",
            "lastName": "Tester",
            "address": "",
            "mobile": "",
            "notes": "",
            "organization": "Vanilla",
            "phone": "",
            "trusted": false,
            "welcomeEmailSent": false,
            "facebookURL": "",
            "googlePlusURL": "",
            "linkedinURL": "",
            "twitterHandle": "",
            "createdAt": "0001-01-01T00:00:00Z",
            "createdBy_users_id": 166240,
            "updatedAt": "0001-01-01T00:00:00Z",
            "updatedBy_users_id": 166240,
            "company": null,
            "lastTicketDate": null,
            "numTickets": 11
        },
        {
            "id": 85469,
            "timezoneId": 0,
            "avatarURL": "https://vanillacompany.teamwork.com/desk/images/examples/noPhoto2.png",
            "email": "codebreaker@vanillacompany.com",
            "contacts": [
                {
                    "id": 45002,
                    "value": "codebreaker@vanillacompany.com",
                    "type": "email",
                    "isMain": true,
                    "createdAt": "0001-01-01T00:00:00Z"
                }
            ],
            "externalId": "",
            "extraData": "",
            "firstName": "Code",
            "jobTitle": "",
            "language": "en",
            "lastName": "Breaker",
            "address": "",
            "mobile": "",
            "notes": "",
            "organization": "Vanilla",
            "phone": "",
            "trusted": false,
            "welcomeEmailSent": false,
            "facebookURL": "",
            "googlePlusURL": "",
            "linkedinURL": "",
            "twitterHandle": "",
            "createdAt": "0001-01-01T00:00:00Z",
            "createdBy_users_id": 166240,
            "updatedAt": "2016-05-04T20:46:10Z",
            "updatedBy_users_id": 166240,
            "company": null,
            "lastTicketDate": "2017-03-22T19:24:47Z",
            "numTickets": 5
        },
        {
            "id": 69421,
            "timezoneId": 0,
            "avatarURL": "https://vanillacompany.teamwork.com/desk/images/examples/noPhoto3.png",
            "email": "enduser@vanillacompany.com",
            "contacts": [
                {
                    "id": 45032,
                    "value": "enduser@vanillacompany.com",
                    "type": "email",
                    "isMain": true,
                    "createdAt": "2016-02-03T18:57:16Z"
                }
            ],
            "externalId": "",
            "extraData": "",
            "firstName": "End",
            "jobTitle": "",
            "language": "",
            "lastName": "User",
            "address": "",
            "mobile": "",
            "notes": "",
            "organization": "",
            "phone": "999-777-8888",
            "trusted": false,
            "welcomeEmailSent": false,
            "facebookURL": "",
            "googlePlusURL": "",
            "linkedinURL": "",
            "twitterHandle": "",
            "createdAt": "2016-02-03T18:57:16Z",
            "createdBy_users_id": 015874,
            "updatedAt": "2016-04-05T16:49:26Z",
            "updatedBy_users_id": 015874,
            "company": null,
            "lastTicketDate": "2016-04-05T16:48:27Z",
            "numTickets": 23
        },
    ],
    "totalCustomers": 1294
}

谢谢你。

标签: c#asp.netjsonrazor-pagessystem.text.json

解决方案


你的 Json 很好,你只是混淆了一些反序列化的目标。使用您现有的代码,我将进行这些更改。

在类RootObject中将属性更改Customers为类型List<Customer>

public List<Customer> Customers { get; set; }

在 Teamwork.cshtml.cs 中将Customers属性更改为 type RootObject

public RootObject Customers { get; private set; }

然后将反序列化行更改为:

Customers = await JsonSerializer.DeserializeAsync<RootObject>(responseStream);

最后,作为个人喜好,我会改为RootObject命名为CustomerList.


推荐阅读