【问题标题】:Consuming JSON from another API in own .NET Core API在自己的 .NET Core API 中使用来自另一个 API 的 JSON
【发布时间】:2020-06-27 20:33:32
【问题描述】:

对于我在公司实习的项目,我的任务是创建一个 API,该 API 可以管理其他服务的多个管理界面。这些管理界面由 API 端点控制。

他们让我从他们的“表单引擎”的管理 API 开始。允许“租户”(有使用该引擎的合同的人)进行调查等的 API。我的任务是做一个可以获取租户、创建和删除的接口。平常的。

问题是,我没有从 API 获得任何输出,尽管我应该这样做。这也是我第一次在 .NET Core 中使用 JSON,所以我可能会遗漏一些东西。

/admin/tenants 端点的数据结构如下所示:

{
    "_embedded": {
        "resourceList": [
            {
                "id": "GUID",
                "name": "MockTenant1",
                "key": "mocktenant1",
                "applicationId": "APPGUID",
                "createdAt": "SOMEDATE",
                "updatedAt": "SOMEDATE"
            },
            {
                "id": "GUID",
                "name": "MockTenant2",
                "key": "mocktenant2",
                "applicationId": "APPGUID",
                "createdAt": "SOMEDATE",
                "updatedAt": "SOMEDATE"
            }
        ]
    },
    "_page": {
        "size": 10,
        "totalElements": 20,
        "totalPages": 2,
        "number": 1
    },
    "_links": {
        "self": {
            "href": "SOMELINK"
        },
        "first": {
            "href": "SOMELINK"
        },
        "last": {
            "href": "SOMELINK"
        },
        "next": {
            "href": "SOMELINK"
        }
    }
}

所以我让 Visual Studio 从所述 JSON 自动创建以下结构:

    public class Rootobject
    {
        public _Embedded _embedded { get; set; }
        public _Page _page { get; set; }
        public Dictionary<string, Href> _links { get; set; }
    }

    public class _Embedded
    {
        [JsonProperty("resourceList")]
        public Tenant[] tenantList { get; set; }
    }

    public class Tenant
    {
        public string id { get; set; }
        public string name { get; set; }
        public string key { get; set; }
        public string applicationId { get; set; }
        public DateTime createdAt { get; set; }
        public DateTime updatedAt { get; set; }
    }

    public class _Page
    {
        public int size { get; set; }
        public int totalElements { get; set; }
        public int totalPages { get; set; }
        public int number { get; set; }
    }
    public class Href
    {
        public string href { get; set; }
    }

我将 Classname 从 ResourceList 更改为 Tenant,因为它就是这样。 所以,现在来看获取租户的代码:

        public async Task<List<Tenant>> getTenants()
        {
            List<Tenant> tenantList = new List<Tenant>();
            if (accessToken == "" || validUntil < DateTime.Now)
            {
                getNewAccessToken();
            }
            using (var request = new HttpRequestMessage(new HttpMethod("GET"), baseUrl + "admin/tenants"))
            {
                request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");
                request.Headers.TryAddWithoutValidation("apikey", apiKey);
                using (var response = await httpClient.SendAsync(request))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        try
                        {
                            Rootobject result = JsonConvert.DeserializeObject<Rootobject>(await response.Content.ReadAsStringAsync());
                            tenantList.AddRange(result._embedded.tenantList);
                        }
                        catch (Exception ex)
                        {
                            Debug.Write(ex);
                        }
                    }
                }
            }
            foreach (Tenant t in tenantList)
            {
                Debug.Write(t);
            }
            return tenantList;
        }

Debug.Write(t) 和 return 什么也没给我。这是一个空列表。 有人知道为什么会这样,我能做些什么吗?

提前致谢和亲切的问候 伦纳特

【问题讨论】:

  • 如果您的参数名称与 json 的名称不匹配,您应该使用 jsonProperty 来定义要反序列化的内容。此外,href 的一个类就足够了

标签: c# .net json api asp.net-core


【解决方案1】:
  1. 属性名称必须直接或通过JsonPropertyAttribute匹配json对象名称
public class _Embedded
{
    [JsonProperty("resourceList")]
    public List<Tenant> tenantList { get; set; }
}
  1. 您可以优化hrefs
public class Rootobject
{
    public _Embedded _embedded { get; set; }
    public _Page _page { get; set; }
    public Dictionary<string, Href> _links { get; set; }
}

public class Href
{
    public string href { get; set; }
}
  1. HttpResponseMessageIDisposable
using(var response = await httpClient.SendAsync(request))
{
    // reading response code
}
  1. 根据Documentation

HttpClient 旨在为每个应用程序实例化一次,而不是每次使用。

删除

using (var httpClient = new HttpClient())

并添加字段

private static readonly HttpClient httpClient = new HttpClient();
  1. foreach(Tenant tenant in result._embedded.tenantList)可以优化
foreach(Tenant tenant in result._embedded.tenantList)
{
    tenantList.Add(tenant);
}

或单行

tenantList.AddRange(result._embedded.tenantList);

或者干脆

foreach(Tenant t in result._embedded.tenantList)
{
    Debug.Write(t);
}
return result._embedded.tenantList;

【讨论】:

  • 您好,感谢您的精彩回复。我试过这个,但仍然没有输出。我更改了我的 OP 中的代码以反映我从您的答案中获取的内容并更改了我的代码。如果你有时间,请你再看看好吗?提前致谢。
  • 没关系,我试过了,它奏效了!我忘了我必须连接到 VPN 才能从服务器获得响应。非常感谢!
  • @LNRTLRS public List&lt;Tenant&gt; tenantList { get; set; } 这将为您准备好 List 而不是您可以在没有 AddRange 的情况下直接返回的数组。
猜你喜欢
  • 1970-01-01
  • 2018-04-28
  • 2023-03-18
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多