【问题标题】:JSON to datatable ignore arraysJSON到数据表忽略数组
【发布时间】:2019-01-04 16:15:41
【问题描述】:

我正在尝试编写一个通用方法,它将采用 JSON 字符串并将其转换为 DataTable(它可以做到的最好的)。

在遇到具有数组作为属性之一的 JSON 对象之前,它可以正常工作。

我想做的是忽略数组的属性并尽可能地进行转换。

我有一个示例小提琴来解释我正在尝试做的事情: https://dotnetfiddle.net/cgkNov

public static void Main()
{
    const string JsonObject = @"[{Id:""672af604-495b-4dc0-933e-6c55f56bef82"",""Name"":""1"",""MyArray"":[]}]";
    const string EndResultJsonObject = @"[{Id:""672af604-495b-4dc0-933e-6c55f56bef82"",""Name"":""1""}]";
    var settings = new JsonSerializerSettings
    {
        Error = (obj, args) =>
        {
            var context = args.ErrorContext;

            context.Handled = true;
        }
    };
    var a = JsonConvert.DeserializeObject<DataTable>(JsonObject, settings);

    Console.WriteLine(JsonConvert.SerializeObject(a));

    a = JsonConvert.DeserializeObject<DataTable>(EndResultJsonObject, settings);

    Console.WriteLine(JsonConvert.SerializeObject(a));
}

谢谢, 亚历克斯

【问题讨论】:

标签: c# json datatable json.net


【解决方案1】:

我注意到您如何使用 double " 来包装字段的键和值。在您当前的 JsonObject 示例代码中,您没有将空数组 [] 括在引号中。我尝试将其更改为

const string JsonObject = @"[{Id:""672af604-495b-4dc0-933e-6c55f56bef82"",""Name"":""1"",""MyArray"":""[]""}]";

这至少解决了您当前数据的问题。由于您使用第三方库来执行 JSON 的实际解析,因此您对该过程的控制有限。

也许您可以尝试创建DataTable 类的缩小版本,然后使用这个新版本将 JSON 字符串解析为新 MiniDT 类的对象。如果您需要帮助,请告诉我。

干杯。

【讨论】:

    【解决方案2】:

    使用这个

    const string JsonObject = @"[{Id:""672af604-495b-4dc0-933e-6c55f56bef82"",""Name"":""1"",""MyArray"":[{}]}]";
    

    数组应该这样声明

    我的数组:[{}]

    【讨论】:

      【解决方案3】:

      亚历克斯,

      我找到了 Brian Rogers 的这个答案:Removing empty array members from a JSON string

      我认为这就是您要搜索的内容。试试看,如果不是,我们可以使用它作为灵感来创建代码。

      【讨论】:

        【解决方案4】:

        如果你想跳过数组,你可以使用这样的东西。这只是一个例子,也许你应该改进它。 添加自定义转换器:

        public class SkipArrayConverter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return !objectType.IsArray;
            }
        
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                JArray array = JArray.Load(reader);
                DataTable dataTable = new DataTable();
                int i = 0;
                foreach (JToken token in array.Children())
                {
                    var dataRow = dataTable.NewRow();
                    if (token.Type != JTokenType.Object) continue;
        
                    if (i == 0)
                    {
                        SetColumns(dataTable, token);
                        dataRow = dataTable.NewRow();
                        i++;
                    }
        
                    foreach (JToken jToken in token)
                    {
                        if (((JProperty)jToken).Value.Type != JTokenType.Array)
                        {
                            string name = ((JProperty)jToken).Name;
                            object value = ((JValue)((JProperty)jToken).Value).Value;
                            dataRow[name] = value;
                        }
                    }
        
                    dataTable.Rows.Add(dataRow);
                }
                return dataTable;
            }
        
            private void SetColumns(DataTable dt, JToken token)
            {
                foreach (JToken jToken in token)
                {
                    if (((JProperty)jToken).Value.Type != JTokenType.Array)
                    {
                        string name = ((JProperty)jToken).Name;
                        object value = ((JValue)((JProperty)jToken).Value).Value;
                        Type valueType = value.GetType();
                        dt.Columns.Add(name, valueType);
                    }
                }
            }
        
            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                throw new NotImplementedException();
            }
        }
        

        之后就可以使用了:

        JsonSerializerSettings settings = new JsonSerializerSettings
        {
            Converters = new List<JsonConverter> { new SkipArrayConverter() }
        };
        const string JsonObject = @"[{Id:""672af604-495b-4dc0-933e-6c55f56bef82"",Name:""1"",MyArray:[{}]}]";
        const string EndResultJsonObject = @"[{Id:""672af604-495b-4dc0-933e-6c55f56bef82"",""Name"":""1""}]";
        var a = JsonConvert.DeserializeObject<DataTable>(JsonObject, settings);
        
        Console.WriteLine(JsonConvert.SerializeObject(a));
        
        a = JsonConvert.DeserializeObject<DataTable>(EndResultJsonObject, settings);
        
        Console.WriteLine(JsonConvert.SerializeObject(a));
        

        【讨论】:

        • 这正是我所追求的!谢谢
        猜你喜欢
        • 1970-01-01
        • 2016-09-19
        • 1970-01-01
        • 2017-01-28
        • 2014-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多