title: Deserialize Multidimensional JSON array with ASP.NET Core
body: <p>I have been trying for a few days to find this issue, perhaps I am missing something.</p>
  
  <p>I followed the recommendations from Microsoft when I built my sample application based on GitHub:
  <a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests?view=aspnetcore-3.1</a></p>
  
  <p>Unfortunately it seems this code does not work for what appears to be a multidimensional array.</p>
  
  <p>The hope of my application is to get information from our Teamwork Desk account so we can create reporting with an ASP.NET application.</p>
  
  <p>Any tips or ideas on how to get this working would be great.</p>
  
  <p>Here is my code:</p>
  
  <p>Folder (Models.TeamworkDesk) | Customer.cs</p>
  
  <pre><code>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&lt;Contact&gt; 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&lt;RootObject&gt; Customers { get; set; }
  
          [JsonPropertyName("totalCustomers")]
          public int TotalCustomers { get; set; }
      }
  }
  </code></pre>
  
  <p>Folder (Pages) | Teamwork.cshtml.cs</p>
  
  <pre><code>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&lt;Customer&gt; 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&lt;IEnumerable&lt;Customer&gt;&gt;(responseStream);
  
              }
              else
              {
                  GetCustomersError = true;
                  Customers = Array.Empty&lt;Customer&gt;();
              }
  
          }
      }
  
  }
  </code></pre>
  
  <p>Folder (Pages) | Teamwork.cshtml</p>
  
  <pre><code>@page
  @model Vanilla.Pages.TeamworkModel
  @{
      ViewData["Title"] = "Teamwork Customers";
      Layout = "~/Pages/Shared/_Layout.cshtml";
  }
  
  @if (Model.GetCustomersError)
  {
      &lt;p&gt;Unable to get customers from Teamwork. Please try again later.&lt;/p&gt;
  }
  else
  {
  &lt;ul&gt;
      @foreach (var customer in Model.Customers)
      {
          &lt;li&gt;@customer.FirstName&lt;/li&gt;
      }
  &lt;/ul&gt;
  </code></pre>
  
  <p>JSON Example:</p>
  
  <pre><code>{
      "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
  }
  </code></pre>
  
  <p>Thank you.</p>