使用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
相关产品推荐
相关产品推荐

