【问题标题】:Convert JSON response from REST API into DataTable将来自 REST API 的 JSON 响应转换为 DataTable
【发布时间】:2022-11-13 13:02:58
【问题描述】:

我正在尝试将来自 REST API 的 json 响应转换为 DataTable。以下是我的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RestSharp;
using Newtonsoft.Json;
using System.Data;

namespace RestDemo1
{
    class Program
    {
        static void Main(string[] args)
        {
            getEmployeeData();
        }

        public static void getEmployeeData()
        {
            var client = new RestClient("https://crmscf.vidyasystems.com/api/gen/items.php");
            var request = new RestRequest("items");
            var response = client.Execute(request);
            string vJ = "";

            if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
                string rawResponse = response.Content;
                DataTable tester = (DataTable)JsonConvert.DeserializeObject(rawResponse, (typeof(DataTable)));
            }
        }

        public class Rootobject
        {
            public int success { get; set; }
            public Item[] items { get; set; }

            public class Item
            {
                public string ItemID { get; set; }
                public string ItemName { get; set; }
                public string ItemDesc { get; set; }
                public string MRP { get; set; }
                public string Rate { get; set; }
                public string Unit { get; set; }
                public string Weight { get; set; }
                public string ItemGroup { get; set; }
            }
        }
    }
}

当我尝试将数据转换为表格格式时,出现错误:

DataTable tester = (DataTable)JsonConvert.DeserializeObject(rawResponse, (typeof(DataTable)));

错误消息 - Newtonsoft.Json.JsonSerializationException: '读取 DataTable 时出现意外的 JSON 令牌。预期 StartArray,得到 StartObject。路径'',第 1 行,位置 1。

【问题讨论】:

  • 调试!在string rawResponse = response.Content; 之后设置断点现在检查json。
  • 我能够得到回应。我什至可以使用dynamic json = JsonConvert.DeserializeObject(rawResponse)反序列化它
  • @SDS 首先将其转换为数组,然后反序列化数组string[] stringArray = new string[]{ someString };
  • 您能与我们分享一个示例 json 吗?
  • 错误说明了一切:Expected StartArray, got StartObject - json 不是应有的数组。

标签: c# json.net


【解决方案1】:

您的回复是 Rootobject 类型,而不是 DataTable 类型。因此,您不能将 response.Content 反序列化为 DataTable 类型。

你需要做什么:

  1. response.Content 反序列化为Rootobject 实例。

  2. Rootobject 实例中提取itemsList<Rootobject.Item> 类型的列表)。

  3. 通过扩展方法IListExtensions.ToDataTable<T>(this IList<T> list)List<Rootobject.Item>转换为DataTable

    string rawResponse = response.Content;
                    
    var root = JsonConvert.DeserializeObject<Rootobject>(rawResponse);
                    
    DataTable dt = root.items.ToDataTable<Rootobject.Item>();
    
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    
    public static class IListExtensions
    {
        public static DataTable ToDataTable<T>(this IList<T> list)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
            DataTable dataTable = new DataTable();
    
            foreach (PropertyDescriptor property in properties)
                dataTable.Columns.Add(property.Name, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
    
            if (list == null)
                return dataTable;
    
            foreach (T item in list)
            {
                DataRow row = dataTable.NewRow();
                foreach (PropertyDescriptor property in properties)
                    row[property.Name] = property.GetValue(item) ?? DBNull.Value;
    
                dataTable.Rows.Add(row);
            }
    
            return dataTable;
        }
    }
    

【讨论】:

  • 它在“foreach(列表中的 T 项)”行中的 ToDataTable<T> 方法中引发异常 ** System.NullReferenceException: '对象引用未设置为对象的实例。'**
  • 看起来listnull,检查它是否是null,如果是null则阻止它执行foreach循环。检查我的最新更改以获取答案。
  • 它实际上给我一个空列表。不知道为什么。您是否有任何代码从虚拟休息 api 获取 json 响应并以表格格式显示数据?
  • 检查了这个demo。我使用了您提供的 API URL,它可以正常工作。在转换为 DataTable 之前,您需要检查 API 是否返回响应以及它是否与您的模型类匹配。
  • FiddleHelper.WriteTable(dt); 是否有替代品来显示 ta 数据?
【解决方案2】:

很抱歉之前的答案,我认为这将解决您的问题:

public static async Task Main(string[] args)
{
    using(HttpClient client = new())
    {
        var response = await client.GetStringAsync("https://crmscf.vidyasystems.com/api/gen/items.php");
        JObject jsonObject = JObject.Parse(response);
        var items = JsonConvert.SerializeObject(jsonObject["items"]);
        DataTable tester = (DataTable)JsonConvert.DeserializeObject(items, (typeof(DataTable)));
    }
    Console.WriteLine("Hello, World!");
}

【讨论】:

  • 我能够得到回复,直到JObject jsonObject = JObject.Parse(response.Content);。在那之后,我对 itams 和 dt 变得空了
  • 这是为将响应转换为数据表而创建的控制台应用程序:github.com/Hawre1987/DotNetDataTableFromJson.git
  • 这需要来自文件的 json 响应,但我正在处理从 api 的 url 获取的响应。
  • @SDS,我已经更新了从您的 API 端点而不是文件获取 json 的答案,请检查一下。
  • 我在JObject jsonObject = JObject.Parse(response.Content); 行出现错误“字符串”不包含“内容”的定义,并且找不到接受“字符串”类型的第一个参数的可访问扩展方法“内容”(您是否缺少 using 指令或程序集引用?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 2016-09-04
  • 1970-01-01
  • 2017-12-01
  • 2018-07-15
  • 2017-09-13
相关资源
最近更新 更多