如何将获取的 API 数据映射到 JSON 对象以进行循环

How to map fetched API data into JSON object for looping

我有以下工作代码从 Azure API 获取 JSON 数据:

@code {
string responseBody; 


protected override async Task OnInitializedAsync()
{
    var personalaccesstoken = "*******";
    var uri = "https://dev.azure.com/*****";

    using (HttpClient client = new HttpClient())
    {
      client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

      client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalaccesstoken))));

      HttpResponseMessage response = client.GetAsync(uri).Result;
      response.EnsureSuccessStatusCode();
      responseBody = await response.Content.ReadAsStringAsync();
      System.Diagnostics.Debug.Print(">>> responseBody" + responseBody);
    }
  }
  
}

我可以在控制台看到JSON对象,所以上面的代码没有问题。 作为参考,这是我看到的输出的一部分。

{
 "count": 50,
  "value": [
    {
    "_links": {
        "self": {
           "href": "https://dev.azure.com/****"
        }
      }
    ....
    }
}

不幸的是,在 C# 中无法对此响应执行 foreach,所以在阅读了一些内容后我意识到我需要为响应对象创建一个 class 以便循环遍历它。

@code {
  public class BuildItem
  {
    public string count { get; set;  }
    public List<Build> builds { get; set;  }
  }

  public class Build
  {
    public int id { get; set; }
    public string _links { get; set; }
    public string tags { get; set; }
    public string plans { get; set; }
    public string queueTime { get; set; }
 }

接下来,我将这一行添加到 @code{} 块的底部

BuildItem data = JsonConvert.DeserializeObject<BuildItem>(responseBody); 
foreach (var res in data.builds)
{
   Console.WriteLine($"Id: {res._links}"); 
}

我希望看到每个 link 或仅列出 JSON 的 _links 部分,但我却收到此错误:

System.NullReferenceException: 'Object reference not set to an instance of an object.'
MyBuilds.Components.Builds.BuildItem.builds.get returned null.

错误来自:

感谢您的帮助

**更新:完整 JSON 对象 **

我只需要 _linksidbuildNumberstatus

{
  "count":2,
  "value":[
    {
      "_links":{
        "self":{
          "href":"****"
        },
        "web":{
          "href":"****"
        },
        "sourceVersionDisplayUri":{
          "href":"****"
        },
        "timeline":{
          "href":"****"
        },
        "badge":{
          "href":"****"
        }
      },
      "properties":{
        
      },
      "tags":[
        
      ],
      "validationResults":[
        
      ],
      "plans":[
        {
          "planId":"****"
        }
      ],
      "triggerInfo":{
        "pr.number":"11244",
        "pr.isFork":"False",
        "pr.triggerRepository":"****",
        "pr.triggerRepository.Type":"TfsGit"
      },
      "id":106479,
      "buildNumber":"****",
      "status":"****",
      "result":"****",
      "queueTime":"****",
      "startTime":"****",
      "finishTime":"****",
      "url":"****",
      "definition":{
        "drafts":[
          
        ],
        "id":554,
        "name":"****",
        "url":"****",
        "uri":"****",
        "path":"****",
        "type":"****",
        "queueStatus":"****",
        "revision":7,
        "project":{
          "id":"****",
          "name":"****",
          "url":"****",
          "state":"****",
          "revision":****,
          "visibility":"****",
          "lastUpdateTime":"****"
        }
      },
      "buildNumberRevision":5,
      "project":{
        "id":"****",
        "name":"****",
        "url":"****",
        "state":"wellFormed",
        "revision":749,
        "visibility":"private",
        "lastUpdateTime":"****"
      },
      "uri":"****",
      "sourceBranch":"****",
      "sourceVersion":"****",
      "queue":{
        "id":313,
        "name":"Azure Pipelines",
        "pool":{
          "id":36,
          "name":"Azure Pipelines",
          "isHosted":true
        }
      },
      "priority":"normal",
      "reason":"pullRequest",
      "requestedFor":{
        "displayName":"****",
        "url":"****",
        "_links":{
          "avatar":{
            "href":"****"
          }
        },
        "id":"****",
        "uniqueName":"****",
        "imageUrl":"****",
        "descriptor":"****"
      },
      "requestedBy":{
        "displayName":"****",
        "url":"****",
        "_links":{
          "avatar":{
            "href":"****"
          }
        },
        "id":"****",
        "uniqueName":"****",
        "imageUrl":"****",
        "descriptor":"****"
      },
      "lastChangedDate":"****",
      "lastChangedBy":{
        "displayName":"****",
        "url":"****",
        "_links":{
          "avatar":{
            "href":"****"
          }
        },
        "id":"****",
        "uniqueName":"****",
        "imageUrl":"****",
        "descriptor":"****"
      },
      "parameters":"{}",
      "orchestrationPlan":{
        "planId":"****"
      },
      "logs":{
        "id":0,
        "type":"Container",
        "url":"****"
      },
      "repository":{
        "id":"****",
        "type":"****",
        "clean":null,
        "checkoutSubmodules":false
      },
      "keepForever":true,
      "retainedByRelease":false,
      "triggeredByBuild":null
    }
  ]
}

非常感谢

尝试以下:

你的 JSON 字符串有 value 作为 array/list 但你的属性名称是你创建的构建尝试将 builds 更改为 value

@code {
  public class BuildItem
  {
    public string count { get; set;  }
    public List<Build> value{ get; set;  }
  }

  public class Build
  {
    public int Id { get; set; }
    public Links _links { get; set; }
    public string Tags { get; set; }
    public string Plans { get; set; }
    public string QueueTime { get; set; }
    public string Status { get; set; }
    public string BuildNumber{get;set;}
 }

也用于 _links,因此 _links 也是一个对象,并且您已经创建了它的字符串,因此您需要为 _links 以及其中的属性创建一个 class。然后 self 属性 也是一个对象,因此您还需要创建 class 和 属性

class Links {
public SelfModel Self{get;set;}
 public WebModel Web{get;set;}
}



  class SelfModel{
    public string Href{get;set;}
    }
    class WebModel{
    public string Href{get;set;}
    }

在 C# 中为 JSON 字符串创建模型时要小心。 C# 模型将遵循驼峰式大小写 属性 name.

而不是

public class BuildItem
{
  public string count { get; set;  }
  public List<Build> value{ get; set;  }
}

试试

public class BuildItem
{
  public string count { get; set;  }
  public List<Build> value{ get; set;  } = New List<Build>();
}

您的模特:

public class Self
{
    public string href { get; set; }
}

public class Web
{
    public string href { get; set; }
}

public class SourceVersionDisplayUri
{
    public string href { get; set; }
}

public class Timeline
{
    public string href { get; set; }
}

public class Badge
{
    public string href { get; set; }
}

public class Links
{
    public Self self { get; set; }
    public Web web { get; set; }
    public SourceVersionDisplayUri sourceVersionDisplayUri { get; set; }
    public Timeline timeline { get; set; }
    public Badge badge { get; set; }
}

public class Value
{
    public Links _links { get; set; }
    public int id { get; set; }
    public string buildNumber { get; set; }
    public string status { get; set; }
}

public class Root
{
    public int count { get; set; }
    public List<Value> value { get; set; }
}

请求后:

string responseBody = await response.Content.ReadAsStringAsync();
if(responseBody is {Length: > 0})
{
  var result= JsonSerializer.Deserialize<Root>(responseBody);
};

处理 Json 对象的第一步是确保您在 C# 对象结构和命名法与 Json 对象结构和命名法之间正确映射。

这是你原来的更简单的 json 和用于反序列化它的对象集放入测试页。找出映射的一种方法是创建一个对象实例并将其序列化,以便您可以比较两者。你可以看到这是代码。

一旦你有了你的 C# 对象,你就可以做任何你想做的迭代。

@page "/"

@using System.Text.Json;
@using System.Text.Json.Serialization;
<h2>Test Page</h2>

<code>
    Test JSON : @jsonExample
</code>

@code {
    private string jsonData = @"
{
 ""count"": 2,
  ""value"": [
    {
    ""_links"": {
        ""self"": {
           ""href"": ""https://dev.azure.com/****""
        }
      }
    },
    {
    ""_links"": {
        ""self"": {
           ""href"": ""https://dev.azure.com/****""
        }
      }
    }
  ]
}
";

    private string jsonExample = string.Empty;
    protected override void OnInitialized()
    {
        var z = new LinkData { href = "http://www.me.com" };
        var l = new Link { self = z };
        var ls = new LinkValue { _links = l };

        var y = new Data() { count = 2 };
        y.value.Add(ls);

        jsonExample = JsonSerializer.Serialize<Data>(y);
        var x = JsonSerializer.Deserialize<Data>(jsonData);
        var g = true;
    }

    public class Data
    {
        public int count { get; set; }
        public List<LinkValue> value { get; set; } = new List<LinkValue>();

    }

    public class LinkValue
    {
        public Link _links { get; set; } = new Link();
    }

    public class Link
    {
        public LinkData? self { get; set; }
    }

    public class LinkData
    {
        public string? href { get; set; }
    }

}