猿问

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

我正在尝试调用两个 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"})或将反序列化类型更改为数组或实现集合接口的类型。


对此有什么想法/提示吗?


holdtom
浏览 174回答 1
1回答

互换的青春

我测试了我在评论中所说的。第二个响应是字符串的 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{&nbsp; &nbsp; static void Main(string[] args)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var invoker = new JsonMockInvoker();&nbsp; &nbsp; &nbsp; &nbsp; var jsonObj = invoker.Get<SomeClass>("API_URL1");&nbsp; &nbsp; &nbsp; &nbsp; var jsonObj2 = invoker.Get<string[]>("API_URL2");&nbsp; &nbsp; }}class SomeClass{&nbsp; &nbsp; public string Name { get; set; }&nbsp; &nbsp; //other properties}public class JsonMockInvoker:JsonInvoker{&nbsp; &nbsp; public override string InvokeRest(string url)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if (url == "API_URL1")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return "{\"Name\": \"Apple\",\"Expiry\": \"2008-12-28T00:00:00\",\"Price\": 3.99,\"Sizes\": [\"Small\",\"Medium\",\"Large\"]}";&nbsp; &nbsp; &nbsp; &nbsp; if (url == "API_URL2")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 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\"]";&nbsp; &nbsp; &nbsp; &nbsp; throw new NotImplementedException();&nbsp; &nbsp; }}public class JsonInvoker{&nbsp; &nbsp; public T Get<T>(string requestUri)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; var result = InvokeRest(requestUri);&nbsp; &nbsp; &nbsp; &nbsp; return result != null ? JsonConvert.DeserializeObject<T>(result) : default(T);&nbsp; &nbsp; }&nbsp; &nbsp; public virtual string InvokeRest(string url)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; using (var handler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })&nbsp; &nbsp; &nbsp; &nbsp; using (var httpClient = CreateNewRequest(handler))&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var httpTask = httpClient.GetAsync(url);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var response = httpTask.Result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.EnsureSuccessStatusCode();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (response.IsSuccessStatusCode)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return response.Content.ReadAsStringAsync().Result;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp; private HttpClient CreateNewRequest(HttpClientHandler handler)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; HttpClient client = new HttpClient(handler);&nbsp; &nbsp; &nbsp; &nbsp; client.DefaultRequestHeaders.Accept.Clear();&nbsp; &nbsp; &nbsp; &nbsp; client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));&nbsp; &nbsp; &nbsp; &nbsp; return client;&nbsp; &nbsp; }}字符串值不是 JSON 格式 - 您必须手动解析它们://parse to typed objectvar parsedObject = jsonObj2.Select(a => new{&nbsp; &nbsp; Id = Regex.Match(a, "(?<=Id=)[^,]*").Value,&nbsp; &nbsp; Name = Regex.Match(a, "(?<=Name=)[^,]*").Value});//parse to dictionaryvar regex = new Regex("([\\s]|^)(?<key>[^=]+)=(?<value>[^,]*)");var parsed = jsonObj2.Select(a =>{&nbsp; &nbsp; var dictionary = new Dictionary<string, string>();&nbsp; &nbsp; foreach (Match match in regex.Matches(a))&nbsp; &nbsp; &nbsp; &nbsp; dictionary[match.Groups["key"].Value] = match.Groups["value"].Value;&nbsp; &nbsp; return dictionary;});
随时随地看视频慕课网APP
我要回答