You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Newtonsoft.Json序列化含MySqlDateTime的DataTable时日期值为null的问题

我之前也碰到过类似的问题,核心原因是Newtonsoft.Json默认不识别MySqlDateTime(MariaDB对应的自定义日期类型),当它遇到这种非标准的.NET类型时,不知道如何序列化,就直接输出null了。结合你已经发现的GetDateTime()转换方法,这里给你几个可行的解决方案:

方案1:提前将DataTable中的MySqlDateTime转为DateTime类型

在序列化之前,遍历DataTable的行,把delivertime列的类型转换为.NET标准的DateTime,这样JsonConvert就能正常识别并序列化了:

DataTable dt = new DataTable();
string sql = "select ig, gid, delivertime from t_storage";
MariadbHelper db = new MariadbHelper();// a dbhelper
db.excute(sql).Fill(dt);// pull the sql result into dt

// 转换delivertime列的类型和值
if (dt.Columns.Contains("delivertime"))
{
    // 添加一个临时的DateTime类型列
    dt.Columns.Add("delivertime_temp", typeof(DateTime));
    foreach (DataRow row in dt.Rows)
    {
        if (row["delivertime"] != DBNull.Value)
        {
            MySql.Data.Types.MySqlDateTime mySqlDt = (MySql.Data.Types.MySqlDateTime)row["delivertime"];
            row["delivertime_temp"] = mySqlDt.GetDateTime();
        }
    }
    // 删除原列,并重命名临时列
    dt.Columns.Remove("delivertime");
    dt.Columns["delivertime_temp"].ColumnName = "delivertime";
}

// 现在序列化就能得到正确的日期值了
string ret = JsonConvert.SerializeObject(dt, Formatting.Indented);

方案2:自定义JsonConverter处理MySqlDateTime

如果不想修改DataTable的结构,可以写一个自定义的Json转换器,告诉Newtonsoft.Json如何处理MySqlDateTime类型:

首先定义转换器类:

public class MySqlDateTimeConverter : JsonConverter<MySql.Data.Types.MySqlDateTime>
{
    public override void WriteJson(JsonWriter writer, MySql.Data.Types.MySqlDateTime value, JsonSerializer serializer)
    {
        // 仅当MySqlDateTime有效时,转换为DateTime序列化;否则输出null
        if (value.IsValid)
        {
            serializer.Serialize(writer, value.GetDateTime());
        }
        else
        {
            writer.WriteNull();
        }
    }

    public override MySql.Data.Types.MySqlDateTime ReadJson(JsonReader reader, Type objectType, MySql.Data.Types.MySqlDateTime existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 如果需要反序列化功能,可以在这里实现(根据你的需求调整)
        if (reader.Value is DateTime dt)
        {
            return new MySql.Data.Types.MySqlDateTime(dt);
        }
        return MySql.Data.Types.MySqlDateTime.MinValue;
    }
}

然后在序列化时指定使用这个转换器:

DataTable dt = new DataTable();
string sql = "select ig, gid, delivertime from t_storage";
MariadbHelper db = new MariadbHelper();
db.excute(sql).Fill(dt);

// 配置序列化设置,添加自定义转换器
var jsonSettings = new JsonSerializerSettings
{
    Formatting = Formatting.Indented,
    Converters = new List<JsonConverter> { new MySqlDateTimeConverter() }
};

string ret = JsonConvert.SerializeObject(dt, jsonSettings);

方案3:从SQL查询时直接转换为标准DateTime

如果你的MariaDB版本支持,也可以在SQL查询阶段就把日期字段转成标准的DateTime格式,这样DataTable中拿到的就是.NET原生的DateTime类型,无需后续处理:

// 使用CAST函数将数据库日期类型转为标准DateTime
string sql = "select ig, gid, CAST(delivertime AS DATETIME) AS delivertime from t_storage";

填充DataTable后,delivertime列的类型就是DateTime,序列化自然会输出正确的日期值。

内容的提问来源于stack exchange,提问作者Lucavin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:14:34