为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 C#.Net 存储不同响应类型的 API 结果集

如何使用 C#.Net 存储不同响应类型的 API 结果集

C#
holdtom 2021-11-21 14:50:33
我正在尝试调用两个 API 并存储它们的响应。以下是 API 响应类型:API1 响应:{  "Name": "Apple",  "Expiry": "2008-12-28T00:00:00", "Price": 3.99, "Sizes": [ "Small", "Medium", "Large"  ]}API2 响应:["Name=xyz, Id=1, Version=1","Name=abc, Id=1, Version=2","Name=hgf, Id=1, Version=3","Name=utgds, Id=1, Version=4","Name=kfgf, Id=2, Version=1"]下面是调用 API 并获取结果集的代码。var jsonObj = Get<SomeClass>("API_URL1");var jsonObj2 = Get<Test>("API_URL2"); public T Get<T>(string requestUri)        {            T response = default(T);            using (var handler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })            {                using (var httpClient = CreateNewRequest(handler))                {                    var httpTask = httpClient.GetAsync(requestUri);                    var response = task.Result;                    response.EnsureSuccessStatusCode();                    if (response.IsSuccessStatusCode)                    {                        var result = response.Content.ReadAsStringAsync().Result;                        var res = JsonConvert.DeserializeObject<T>(result);                    }                }            }            return res;        } private HttpClient CreateNewRequest(HttpClientHandler handler)    {        HttpClient client = new HttpClient(handler);        client.DefaultRequestHeaders.Accept.Clear();        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));        return client;    }public class Test{    public string Name { get; set; }    public int Id { get; set; }    public int Version { get; set; }}同样,我创建了一个类来保存 API1 响应。我能够存储 API1 响应但是在存储 API2 响应时我收到此错误消息。无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型,因为该类型需要 JSON 对象(例如 {"name":"value"})才能正确反序列化。要修复此错误,请将 JSON 更改为 JSON 对象(例如 {"name":"value"})或将反序列化类型更改为数组或实现集合接口的类型。对此有什么想法/提示吗?
查看完整描述

1 回答

?
互换的青春

TA贡献1797条经验 获得超6个赞

我测试了我在评论中所说的。第二个响应是字符串的 JSON 数组。您应该将其反序列化为字符串数组 ( string[]) 或字符串集合 ( List<string>)。以下按预期工作:


var response = "[\"Name=xyz, Id=1, Version=1\", \"Name=abc, Id=1, Version=2\", \"Name=hgf, Id=1, Version=3\", \"Name=utgds, Id=1, Version=4\", \"Name=kfgf, Id=2, Version=1\"]";

var result = JsonConvert.DeserializeObject<string[]>(response);

总结:而不是Get<Test>使用Get<string[]>. 您只需要解析字符串,但这似乎是另一个问题。


下面的完整演示(故意嘲笑 url 调用):


class Program

{

    static void Main(string[] args)

    {

        var invoker = new JsonMockInvoker();

        var jsonObj = invoker.Get<SomeClass>("API_URL1");

        var jsonObj2 = invoker.Get<string[]>("API_URL2");

    }

}


class SomeClass

{

    public string Name { get; set; }

    //other properties

}


public class JsonMockInvoker:JsonInvoker

{

    public override string InvokeRest(string url)

    {

        if (url == "API_URL1")

            return "{\"Name\": \"Apple\",\"Expiry\": \"2008-12-28T00:00:00\",\"Price\": 3.99,\"Sizes\": [\"Small\",\"Medium\",\"Large\"]}";

        if (url == "API_URL2")

            return "[\"Name=xyz, Id=1, Version=1\", \"Name=abc, Id=1, Version=2\", \"Name=hgf, Id=1, Version=3\", \"Name=utgds, Id=1, Version=4\", \"Name=kfgf, Id=2, Version=1\"]";

        throw new NotImplementedException();

    }

}


public class JsonInvoker

{

    public T Get<T>(string requestUri)

    {

        var result = InvokeRest(requestUri);

        return result != null ? JsonConvert.DeserializeObject<T>(result) : default(T);

    }


    public virtual string InvokeRest(string url)

    {

        using (var handler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })

        using (var httpClient = CreateNewRequest(handler))

        {

            var httpTask = httpClient.GetAsync(url);

            var response = httpTask.Result;

            response.EnsureSuccessStatusCode();

            if (response.IsSuccessStatusCode)

            {

                return response.Content.ReadAsStringAsync().Result;

            }

        }

        return null;

    }


    private HttpClient CreateNewRequest(HttpClientHandler handler)

    {

        HttpClient client = new HttpClient(handler);

        client.DefaultRequestHeaders.Accept.Clear();

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        return client;

    }

}

字符串值不是 JSON 格式 - 您必须手动解析它们:


//parse to typed object

var parsedObject = jsonObj2.Select(a => new

{

    Id = Regex.Match(a, "(?<=Id=)[^,]*").Value,

    Name = Regex.Match(a, "(?<=Name=)[^,]*").Value

});


//parse to dictionary

var regex = new Regex("([\\s]|^)(?<key>[^=]+)=(?<value>[^,]*)");

var parsed = jsonObj2.Select(a =>

{

    var dictionary = new Dictionary<string, string>();

    foreach (Match match in regex.Matches(a))

        dictionary[match.Groups["key"].Value] = match.Groups["value"].Value;

    return dictionary;

});


查看完整回答
反对 回复 2021-11-21
  • 1 回答
  • 0 关注
  • 173 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信