【问题标题】:Unable to read json comes from Web API in C#无法读取 json 来自 C# 中的 Web API
【发布时间】:2018-11-02 09:27:41
【问题描述】:

无法将 webapi 值读取到列表对象。请查看链接http://prntscr.com/lcmw7q处的截图值。

错误是 Newtonsoft.Json.JsonSerializationException: '无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List`1[ StudentProfileClient.StudentInfo]',因为该类型需要 JSON 数组(例如 [1,2,3])才能正确反序列化。 要修复此错误,请将 JSON 更改为 JSON 数组(例如 [1,2,3])或更改反序列化类型,使其成为普通的 .NET 类型(例如,不是像整数这样的原始类型,而不是像可以从 JSON 对象反序列化的数组或列表。 JsonObjectAttribute 也可以添加到类型中以强制它从 JSON 对象反序列化。 路径“数据”,第 2 行,位置 10。'

class StudentInfo
    {     




        public string cellPhone { get; set; }

        public string gender { get; set; }

        public string dateOfBirth { get; set; }
    }

 class RootClass
    {

        public int TotalCount { get; set; }
        public List<StudentInfo> stdinfo { get; set; }


    }
    static async Task GetData()
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://203.81.70.102:8092/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                HttpResponseMessage response;

                response = await client.GetAsync("control/qZkNkcGgWq6PiVbJzQ2=/student-profiles");

                if (response.IsSuccessStatusCode)
                {
                    List<StudentInfo> RootClass = new List<StudentInfo>();
                    RootClass = await response.Content.ReadAsAsync<List<StudentInfo>>();

                }

            }
        }

【问题讨论】:

  • 您不能使用 JsonConvert.DeserializeObject 从您的 API 响应中直接反序列化。
  • 你能告诉我我应该在哪里更正我的代码..我会非常有帮助
  • 这些都是假的。感谢您的提醒...
  • @Md.RayhanKhan,你能显示你的 json 吗?

标签: c# asp.net-web-api


【解决方案1】:

您不能使用 JsonConvert.DeserializeObject 从您的 API 响应中直接反序列化。 -

 JObject jsonResponse = JObject.Parse(jsonString);
    JObject objResponse = (JObject)jsonResponse["response"];
    Dictionary<string, JArray> _Data = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, JArray>>(objResponse.ToString());

【讨论】:

    【解决方案2】:

    不要将 RootClass 声明为 List,而是使用:

    var RootClass = await response.Content.ReadAsAsync()

    在该行中放置一个断点,并检查从 API 返回的 Type。由于 var 将接受任何内容,因此您可以检查响应。基本上,您的错误表明您正在尝试将 CAST 转换为无效类型,因此反序列化无法正常工作。

    似乎返回的对象是一个数组,也许您需要获取该数组并将其转换为一个列表,或者甚至是一个与您期望的完全不同的对象,具有其他属性等...

    最佳解决方法 -> 调试,并确保您使用正确的类型进行反序列化

    【讨论】:

    • "Content.ReadAsAsync>" 为什么">" 我猜这是一个错字。
    • 您仍在尝试将其转换为 List (在 ReadAsAsync 的通用参数中)...不幸的是,我无法在此处运行您的代码,但我很确定这是您的错误 - 无效的演员表。尝试使用没有 ReadAsAsync 泛型的 Object Read 或重载。
    • 你也可以使用 POSTMAN 来检查这个 API 的返回,然后相应地设置你的类代码
    【解决方案3】:

    简单的解决方案,你需要一个包装器

    这在实践中是什么样的?它只是意味着返回对象列表的 API 将列表包装在顶级对象中。例如,假设您的 API 中有一个 Person 数据类型。如果你 GET 一个人,你可能会得到以下 JSON 响应:

    { "name": "John Smith" }
    

    到目前为止一切都很好。但是如果你想要一个列表而不是一个列表呢?最直观的方式可能如下:

    [{"name": "John Smith"}, {"name": "Jane Smith"}]
    

    但这正是我们需要避免的情况。因此我们需要 对这样的列表使用顶级对象,具有单个数据属性:

    {"data": [{"name": "John Smith"}, {"name": "Jane Smith"}]}
    

    所以.....

    Class Students{
    public List<StudentInfo> roots{get;set;}
    
    }
    

    保留你的学生班级,添加我班级的学生,然后反序列化;

    【讨论】:

      【解决方案4】:

      1) 在Newtonsoft.json 中使用JObject

      在包管理器控制台中键入以下命令。

      Install-Package Newtonsoft.Json

      if (response.IsSuccessStatusCode)
      {
          string json = await response.Content.ReadAsStringAsync();
      
          JObject jObject = JObject.Parse(json);
      
          List<StudentInfo> studentInfos = jObject["data"].ToObject<List<StudentInfo>>();
      }
      

      输出:


      2) 不使用Newtonsoft.json

      在包管理器控制台中键入以下命令。

      Install-Package Microsoft.AspNet.WebApi.Client

      if (response.IsSuccessStatusCode)
      {
          RootClass rootClass = await response.Content.ReadAsAsync<RootClass>();
      
          List<StudentInfo> studentInfos = rootClass.data;
      }
      

      输出:

      所以你的课程将是

      public class StudentInfo
      {
          public int sl { get; set; }
          public string studentId { get; set; }
          public string studentName { get; set; }
          public string school { get; set; }
          public string program { get; set; }
          public string fatherName { get; set; }
          public string motherName { get; set; }
          public string cellPhone { get; set; }
          public string gender { get; set; }
          public string dateOfBirth { get; set; }
      }
      
      public class RootClass
      {
          public List<StudentInfo> data { get; set; }
          public string message { get; set; }
          public int total { get; set; }
      }
      

      【讨论】:

        【解决方案5】:

        所以你有一个名为 RootClass 的类。 你有一个名为 StudentInfo 的类。

        你希望得到哪一个? 似乎你得到了完全不同的东西。 正如我在这里看到的,https://prnt.sc/lcnlho,您应该创建一个看起来像这样的新类(或更改 RootClass 结构)

         class ResponseContainer
            {
                public List<StudentInfo> data { get; set; }
            }
        

        您应该反序列化到这个 ResponseContainer 类,而不是直接反序列化到 List:

        var response = await response.Content.ReadAsAsync<ResponseContainer>();
        

        附言如果你想使用你的 RootClass,你应该将属性 stdinfo 重命名为“data”,或者像这样添加 JsonProperty 属性:

         class RootClass
            {
                public int TotalCount { get; set; }
        
                [JsonProperty(PropertyName = "data")]
                public List<StudentInfo> stdinfo { get; set; }
            }
        

        【讨论】:

          猜你喜欢
          • 2014-07-28
          • 1970-01-01
          • 1970-01-01
          • 2020-12-10
          • 2016-10-18
          • 1970-01-01
          • 1970-01-01
          • 2018-04-28
          • 1970-01-01
          相关资源
          最近更新 更多