栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在自定义类上反序列化DataTable属性后,DateTime列类型变为String类型

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在自定义类上反序列化DataTable属性后,DateTime列类型变为String类型

这个问题
似乎是,Newtonsoft的

DataSetConverter
使用会有限制Newtonsoft的
DataTableConverter
DataTableConverterconverter = new DataTableConverter();
,然后调用它的
ReadJson()
直接方法。因此,永远不会使用您的转换器。

一种解决方案

DataSetConverter
通过改编James Newton-
King的原始代码来创建自己的版本:

public class DataSetConverter<TDataTableConverter> : DataSetConverter where TDataTableConverter : JsonConverter, new(){    // This pre adapted from     // https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/DataSetConverter.cs    // Copyright (c) 2007 James Newton-King    // Licensed under The MIT License (MIT):    // https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md    readonly TDataTableConverter converter = new TDataTableConverter();    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        if (reader.TokenType == JsonToken.Null)        { return null;        }        // handle typed datasets        DataSet ds = (objectType == typeof(DataSet)) ? new DataSet() : (DataSet)Activator.CreateInstance(objectType);        reader.ReadAndAssert();        while (reader.TokenType == JsonToken.PropertyName)        { DataTable dt = ds.Tables[(string)reader.Value]; bool exists = (dt != null); dt = (DataTable)converter.ReadJson(reader, typeof(DataTable), dt, serializer); if (!exists) {     ds.Tables.Add(dt); } reader.ReadAndAssert();        }        return ds;    }}public static class JsonReaderExtensions{    public static void ReadAndAssert(this JsonReader reader)    {        if (reader == null) throw new ArgumentNullException();        if (!reader.Read())        { new JsonReaderException(string.Format("Unexpected end at path {0}", reader.Path));        }    }}

然后添加

DataSetConverter<TypeInferringDataTableConverter>
到您的转换器列表。

顺便说一句,如果您需要做的就是将列类型设置为,

DateTime
当列名包含字符串时
"date"
,您可以考虑创建一个比转换过程更简单的转换
TypeInferringDataTableConverter
器,以反序列化缺少第一列的数据表:

  • 分叉的代码
    DataTableConverter
    。开始时请注意许可证:
// Permission is hereby granted, free of charge, to any person// obtaining a copy of this software and associated documentation// files (the "Software"), to deal in the Software without// restriction, including without limitation the rights to use,// copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the// Software is furnished to do so, subject to the following// conditions://// The above copyright notice and this permission notice shall be// included in all copies or substantial portions of the Software.//// ...
  • 让您的分叉转换器子类为Newtonsoft的子类

    DataTableConverter
    ;删除的所有代码
    WriteJson()

  • 修改

    GetColumnDataType()
    以传递列名并添加必要的逻辑:

    private static Type GetColumnDataType(JsonReader reader, string columnName)

    {
    JsonToken tokenType = reader.TokenType;

    switch (tokenType){    case JsonToken.String:        if (columnName.IndexOf("date", StringComparison.OrdinalIgnoreCase) >= 0) return typeof(DateTime);        return reader.ValueType;    case JsonToken.Integer:    case JsonToken.Boolean:    case JsonToken.Float:    case JsonToken.Date:    case JsonToken.Bytes:        return reader.ValueType;    case JsonToken.Null:    case JsonToken.Undefined:        if (columnName.IndexOf("date", StringComparison.OrdinalIgnoreCase) >= 0) return typeof(DateTime);        return typeof(string);    case JsonToken.StartArray:        reader.ReadAndAssert();        if (reader.TokenType == JsonToken.StartObject)        { return typeof(DataTable); // nested datatable        }        Type arrayType = GetColumnDataType(reader, columnName);        return arrayType.MakeArrayType();    default:        throw JsonSerializationException.Create(reader, "Unexpected JSON token when reading DataTable: {0}".FormatWith(CultureInfo.InvariantCulture, tokenType));}

    }

  • 然后将调用固定为

    GetColumnDataType()
    在第152行附近传递列名称:

    Type columnType = GetColumnDataType(reader, columnName);
  • 存根在任何丢失内部的方法,如

    ReadAndAssert()
    与如图静态扩展方法在这里

*创建您自己的Newtonsoft转换器版本 *的替代解决方案
是,在

[OnDeserialized]
容器类的事件中,使用的其中一个,循环遍历的所有表中的所有
DataSet
列,并将名称包含为
string
(或
object
)类型的列转换为列。如何更改数据表中数据列的数据类型的答案?。
"date"``DateTime



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/437171.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号