如何反序列化 azure devOps 的 json 响应?

How can I deserialize the json response of azure devOps?

我将我的问题转给 Microsoft doc。我请求 azure devOps api 检索特定组织和项目中托管的所有存储库。响应是 json,如下所示:

{
  "count": 3,
  "value": [
    {
      "id": "5febef5a-833d-4e14-b9c0-14cb638f91e6",
      "name": "AnotherRepository",
      "url": "https://dev.azure.com/fabrikam/_apis/git/repositories/5febef5a-833d-4e14-b9c0-14cb638f91e6",
      "project": {
        "id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
        "name": "Fabrikam-Fiber-Git",
        "url": "https://dev.azure.com/fabrikam/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
        "state": "wellFormed"
      },
      "remoteUrl": "https://dev.azure.com/fabrikam/Fabrikam-Fiber-Git/_git/AnotherRepository"
    },
    {
      "id": "278d5cd2-584d-4b63-824a-2ba458937249",
      "name": "Fabrikam-Fiber-Git",
      "url": "https://dev.azure.com/fabrikam/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249",
      "project": {
        "id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
        "name": "Fabrikam-Fiber-Git",
        "url": "https://dev.azure.com/fabrikam/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
        "state": "wellFormed"
      },
      "defaultBranch": "refs/heads/master",
      "remoteUrl": "https://dev.azure.com/fabrikam/_git/Fabrikam-Fiber-Git"
    },
    {
      "id": "66efb083-777a-4cac-a350-a24b046be6be",
      "name": "TestGit",
      "url": "https://dev.azure.com/fabrikam/_apis/git/repositories/66efb083-777a-4cac-a350-a24b046be6be",
      "project": {
        "id": "281f9a5b-af0d-49b4-a1df-fe6f5e5f84d0",
        "name": "TestGit",
        "url": "https://dev.azure.com/fabrikam/_apis/projects/281f9a5b-af0d-49b4-a1df-fe6f5e5f84d0",
        "state": "wellFormed"
      },
      "defaultBranch": "refs/heads/master",
      "remoteUrl": "https://dev.azure.com/fabrikam/_git/TestGit"
    }
  ]
}

Microsoft Doc 表示 api returns 类型 GitRepository[] 所以我想将 json 反序列化为该类型,但我该怎么做??

因为 countvalue 属性 我构建了一个 HelperClass,如下所示:

public class Rootobject
{
    public GitRepository[] value { get; set; }
    public int count { get; set; }
}

但是在反序列化并转换为该对象之后,GitRepository 的所有属性都是空的。

谁能帮我看看为什么所有的属性都是空的??

编辑:这是反序列化

static async Task Main(string[] args)
        {
            string accessToken = "personal_access_token";
            HttpClient httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", string.Empty, accessToken))));

            var response = await httpClient.GetStringAsync("https://dev.azure.com/fabrikam/_apis/git/repositories?api-version=5.1");
            var responseObject = JsonSerializer.Deserialize<Rootobject>(response);
            Console.WriteLine();
        }

你是如何进行反序列化的?你在哪里定义了GitRepository class?您是否尝试反序列化为字符串以检查是否有任何成员已更改?该文档来自 2016 年,此后可能有所更改。

您可以改为使用 Microsoft 提供的 nuget 包来访问这些 API:https://docs.microsoft.com/en-us/azure/devops/integrate/concepts/dotnet-client-libraries?view=azure-devops

我认为您需要的 NuGet 包是 Microsoft.TeamFoundationServer.Client

问题是 System.Text.Json.JsonSerializer 默认为 case-sensitive。 GitRepository 属性 名称是 PascalCase,而您提供的 json 示例包含 CamelCase 名称。因此 JsonSerializer 无法正确反序列化这些属性。

您可以通过提供 JsonSerializerOptions:

来覆盖默认设置
var responseObject = JsonSerializer.Deserialize<Rootobject>(response, new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
});

我还注意到 project 属性 仍然没有被反序列化。我猜这是因为 GitRepository 有一个名为 ProjectReference 的 属性(而不是 Project)并且有一个 DataMember 属性。

看起来 System.Text.Json 不遵守 DataMember 属性。所以我建议你使用 Newtonsoft.Json 库。我测试了它,它工作正常:

var responseObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Rootobject>(response);