为啥 JSON.NET 以这种格式在我的 DataTable 中输出 DateTime 值?

Posted

技术标签:

【中文标题】为啥 JSON.NET 以这种格式在我的 DataTable 中输出 DateTime 值?【英文标题】:why is JSON.NET outputting DateTime values in my DataTable in this format?为什么 JSON.NET 以这种格式在我的 DataTable 中输出 DateTime 值? 【发布时间】:2020-08-03 17:49:58 【问题描述】:

我有一个将 DataTable 序列化为 JSON 的服务,当我检索服务数据时,我想反序列化回 DataTable ...问题是,我不能,因为 JSON.NET 在序列化中添加了一些内容然后它就无法识别...

我的 DataTable 中的所有 DateTime 值最终看起来像这样:

"date_time_value":"IsValidDateTime":true,"Year":2020,"Month":4,"Day":20,"Hour":14,"Minute":50,"Second":46,"Microsecond":0,"Millisecond":0

JSON.NET 像这样输出序列化的 JSON……所以我希望它也知道如何反序列化它……如何将日期序列化为简单的字符串,以便我可以反序列化数据?

编辑:我有一个控制器方法返回数据。

[HttpPost]
[Route("Query")]
public ActionResult<string> Query([FromBody]SqlDto content)

    return Ok(_mysqlGenericService.Query(content.HostnameOrIpAddress, content.Username, content.Password, content.SqlCommand, content.SqlParameters));

以及控制器正在调用的方法:

public string Query(string hostnameOrIp, string username, string password, string sqlCommand, List<SqlParameter> sqlParameters = null)

    var mySqlDatabaseConnection = new MySqlDatabaseConnection(hostnameOrIp, username, password);

    DataTable dt = mySqlDatabaseConnection.Query(sqlCommand, ConvertQueryParamListToTupleList(sqlParameters));

    return JsonConvert.SerializeObject(dt);

MySqlDatabaseConnection 类只是连接到 MySQL 数据库,Query 方法返回一个 DataTable。

请注意,无论我是直接返回DataTable还是使用JsonConvert.SerializeObject()方法在返回之前将其转换为JSON字符串,返回值最终都是相同的JSON。

EDIT2:对于以后可能会来看这个问题的任何人,我错误地假设 DataTable 实际上处于低级别......我认为它只是某种形式的字符串数组,这是完全错误的...... DataTable 对象比我意识到的要复杂得多。它以不同的方式处理来自不同数据源的输入(因此 MS SQL 数据看起来与 MySQL 数据不同,因为它们以不同的对象格式加载到 DataTable 中)。

【问题讨论】:

您控制服务吗?如果是这样,你能告诉我们创建这个 JSON 的代码吗? 我刚刚更新了我的问题以显示相关代码,如果您需要更多信息,请告诉我...如果您认为相关,我可以发布 MySqlDatabaseConnection.Query() 方法...虽然它不应影响任何结果,因为 DataTable 从该方法返回正常 您使用DataTable 而不是更合适的东西(例如具有您定义的属性的具体类型)是否有特殊原因? 实际的推理有点复杂,但有了这个特殊的服务,我需要能够处理任何通用查询和任何通用结果......这就是我使用 DataTable 的原因......令人讨厌的是,这个适用于 Microsoft SQL 的通用输出,但由于某种原因,序列化似乎不适用于 MySQL 数据,我不知道为什么......它们都是序列化之前的 DataTable 对象 另外,我了解安全问题以及所有这些......它被严重锁定。但它需要允许通用数据 【参考方案1】:

您使用的数据库驱动程序似乎没有使用System.DateTime 来表示日期,而且它可能无论如何也不应该使用。从它序列化的属性来看,它似乎是一个MySqlDateTime 类型。 Json.net 无法识别这种类型,但您可能有一个将其视为对象的后备转换器。我自己对这种类型进行了一些测试,它转换为null

我不知道你是否会找到一个现成的转换器,它可能存在于某个地方,幸运的是它应该很容易创建。

public class MySqlDateTimeConverter : JsonConverter<MySqlDateTime>

    public override MySqlDateTime ReadJson(JsonReader reader, Type objectType, MySqlDateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
    
        var dateTime = serializer.Deserialize(reader, typeof(DateTime));
        return new MySqlDateTime((DateTime)dateTime);
    

    public override void WriteJson(JsonWriter writer, MySqlDateTime value, JsonSerializer serializer)
    
        var dateTime = value.GetDateTime();
        serializer.Serialize(writer, dateTime);
    

【讨论】:

我想我错误地认为,一旦 MSSQL 和 MySQL 数据都采用 DataTable 的格式,它们的处理方式相同......显然我需要更多地阅读 DataTable 实际上是什么,因为我认为它只是较低级别的一大串字符串,因此为什么我认为所有 DataTables 的行为都相同......感谢您的解释和代码,将其作为 JsonConvert Serialize 和 Deserialize 方法的转换器插入似乎解决了我的问题

以上是关于为啥 JSON.NET 以这种格式在我的 DataTable 中输出 DateTime 值?的主要内容,如果未能解决你的问题,请参考以下文章

为啥邮递员 POST 方法不提供 `json` 格式的参数?

具有数据类型的 Json.NET 自定义 JsonConverter

Swift - 错误的日期格式(JSON .NET)

为啥我的解决方案找不到 json.net

为啥以这种方式更改此格式化函数会导致 Knockout 绑定开始工作?

为啥当我使用 JSON.NET 反序列化时会忽略我的默认值?