【问题标题】:Am I deserializing my JSON object incorrectly in GetProductAsync?我是否在 GetProductAsync 中错误地反序列化了我的 JSON 对象?
【发布时间】:2018-02-16 21:38:53
【问题描述】:

当我运行这段代码时,我收到以下错误消息:

无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“HttpClientSample.Product”,因为该类型需要 JSON 对象(例如 {"name":"value"})才能正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 对象(例如 {"name":"value"})或将反序列化类型更改为数组或实现集合接口的类型(例如 ICollection、IList),例如可以从 JSON 数组反序列化。也可以将 JsonArrayAttribute 添加到类型中以强制它从 JSON 数组中反序列化。

我以为我告诉我的客户返回一个 JSON……我需要转换我的响应(JsonConvert.DeserializeObject)吗?如果是这样,列表?

使用邮递员的典型响应是:

[
    {
        "id": "1",
        "name": "test",
        "inactive": false           
    },
    {
        "id": "2",
        "name": "test2",
        "inactive": false           
    }
]

谢谢

using Newtonsoft.Json;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;


namespace HttpClientSample
{
   public class Product
  {

    public string id { get; set; }
    public string name { get; set; }
    public bool inactive { get; set; }
  } 

class Program
{

    static HttpClient client = new HttpClient();

    static async Task<Product> GetProductAsync(string path)
    {
        Product product = null;
        HttpResponseMessage response = await client.GetAsync(path);
        if (response.IsSuccessStatusCode)
        {

            product = await response.Content.ReadAsAsync<Product>();
            Console.WriteLine("{0}\t${1}\t{2}", product.id, product.name, product.inactive);
        }
        return product;
    }


    static void Main()
    {
       // RunAsync().GetAwaiter().GetResult();
        RunAsync().Wait();
    }

    static async Task RunAsync()
    {


        // Update port # in the following line.
        var byteArray = Encoding.ASCII.GetBytes("user:pass");
        client.BaseAddress = new Uri("https://localhost:51075/api/products");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

        try
        {

            Product product = new Product();

            // Get the product
            product = await GetProductAsync("https://localhost:51075/api/products");

        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

        Console.ReadLine();
    }
}

}

【问题讨论】:

  • 由您决定出错是否是您的代码的正确行为(我们如何找出您的实际期望?)...您确定标题正是您需要知道的?
  • “典型响应”中的方括号表示(产品项目)列表。因此,您需要相应地更改 ReadAsAsync 方法的通用参数。
  • 这只是您期待单个Product 还是Product 数组的问题。反序列化你所期望的。看起来您期待一个包含一个元素的数组,但仍需要将其反序列化为数组或其他集合。
  • 错误看起来很简单。你有什么不明白的?
  • 更新了我期望的响应示例。

标签: c# json async-await httpclient


【解决方案1】:

更新答案 :) GetResponseAsync 函数:

public static async Task<SetupWebApiResponse> GetResponseAsync(string 
        endpoint)
    {

        string result = "";
        HttpResponseMessage response = await client.GetAsync(endpoint);
        if (response.IsSuccessStatusCode)
        {
            HttpContent content = response.Content;
            result = await content.ReadAsStringAsync();

        }
        return new SetupWebApiResponse(response.StatusCode, result);

    }

SetupWebApiResponse 类:

public class SetupWebApiResponse
{
    public SetupWebApiResponse() { }

    public SetupWebApiResponse(int statusCode, object responseBody)
    {
        this.StatusCode = statusCode;
        this.ResponseBody = responseBody;
    }

    public SetupWebApiResponse(HttpStatusCode statusCode, object responseBody)
        : this((int)statusCode, responseBody)
    {
    }

    /// <summary>
    /// Gets or sets the HTTP status code of the response
    /// </summary>
    public int StatusCode { get; set; }

    /// <summary>
    /// Gets or sets the response body content
    /// </summary>
    public object ResponseBody { get; set; }
}

SetupWebAI 类:

  public class SetupWebAPI
 {

    static string User;
    static string Password;
    static string Endpoint;
    static object Content;

    static SetupWebApiResponse apiResponse;

    public static SetupWebApiResponse GetResponseInStringFormat(string user, string password, string endpoint)
    {
        User = user;
        Password = password;
        Endpoint = endpoint;
        ExecuteResponse().Wait();
        return apiResponse;
    }
    private static async Task ExecuteResponse()
    {
        SetupWebAPIAsync.SetAPIAuthentication(User, Password);
        apiResponse = await SetupWebAPIAsync.GetResponseAsync(Endpoint);
    }

【讨论】:

    【解决方案2】:

    您的问题似乎是您的 JSON 数组格式不正确。为了让我的示例正常工作,我必须在 } 之后添加一个逗号,

    这就是我的工作:

    • 复制 JSON 对象字符串文本
    • 在 Visual Studio 中,我使用“编辑 | 选择性粘贴 | 将 JSON 粘贴为类”-
    • 在命名空间部分内的新 .cs 文件中。

    例子:

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ClassLibrary1
    {
        public class Class1
        {
            public class Product
            {
                public string id { get; set; }
                public string name { get; set; }
                public bool inactive { get; set; }
            }
    
            public void testingClass()
            {
                string testJSONResponse = @"
        [{
                    ""id"": ""1"",
            ""name"": ""test"",
            ""inactive"": false
        },]
    ";
                var myNewCSharpObject = JsonConvert.DeserializeObject<Product[]>(testJSONResponse);
    
            }
        }
    }
    

    【讨论】:

    • 你认为这个建议实际上如何适用于所描述的问题?
    • 我忘记了数组部分...已修复。
    • 你没有解释为什么这是必要的。为什么不直接使用问题已经描述的类?
    • 不,它不是格式错误的 JSON 数组。该问题清楚地描述了错误。
    • @fazlook1,我想提供更多帮助,但我必须重新创建一个模仿您的设置的 REST 服务 :(,我现在没有时间。JSON 太痛苦了,当我使用 JSON 解决其中的一些问题,我最终会使用 XML REST ......哈哈,哦顺便说一句,如果你可以将它放入一个数组中,你可以执行 .ToList(),如果 JsonConvert 更喜欢它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多