C#将dynamic对象转为强类型时DateTimeOffset转DateTime报错如何解决
问题根因
- Newtonsoft.Json反序列化带时区标识的ISO 8601格式时间字符串(你提供的dynamic数据中时间末尾带Z表示UTC时区)时,默认会解析为
System.DateTimeOffset类型,而你的强类型模型中rtfReceivedAt、tifReceivedAt两个字段定义为System.DateTime类型,直接强制类型转换不兼容,触发报错。 - 你的转换代码存在笔误:为
tifReceivedAt赋值时引用了不存在的字段match.ReceivedAt,正确应为match.tifReceivedAt。
解决方案
方案1:调整模型定义(最稳妥)
直接将模型中时间字段的类型从DateTime改为DateTimeOffset,匹配反序列化后的默认类型,无需额外配置:
public class RtfTiffMatchModel : TableEntity { public RtfTiffMatchModel() { } public string visitId { get; set; } public DateTimeOffset rtfReceivedAt { get; set; } public string rtfFilename { get; set; } public DateTimeOffset tifReceivedAt { get; set; } public string tifFilename { get; set; } public string rtfRowKey { get; set; } public string tifRowKey { get; set; } }
如果业务必须使用DateTime类型,可以在字段上加特性指定序列化配置:
[JsonProperty(ItemConverterType = typeof(IsoDateTimeConverter), ItemConverterParameters = new object[] { DateTimeZoneHandling = DateTimeZoneHandling.Utc })] public DateTime rtfReceivedAt { get; set; }
方案2:自动序列化转换(避免手动赋值出错)
不需要手动逐个字段赋值,直接调用Newtonsoft.Json的反序列化方法一键转换:
var rtfTiffMatch = JsonConvert.DeserializeObject<RtfTiffMatchModel>(JsonConvert.SerializeObject(match)); // 补充TableEntity所需的PartitionKey和RowKey rtfTiffMatch.PartitionKey = match.PartitionKey; rtfTiffMatch.RowKey = match.RowKey;
方案3:修改手动转换代码
如果坚持手动赋值,把强制转换改为调用DateTimeOffset的DateTime属性即可:
var rtfTiffMatch = new RtfTiffMatchModel { PartitionKey = match.PartitionKey, RowKey = match.RowKey, rtfReceivedAt = ((DateTimeOffset)match.rtfReceivedAt).DateTime, // 也可按需调用.ToUniversalTime()/ToLocalTime() rtfFilename = match.rtfFilename, rtfRowKey = match.RowKey, tifFilename = match.tifFilename, tifReceivedAt = ((DateTimeOffset)match.tifReceivedAt).DateTime, // 修正字段名笔误 tifRowKey = match.RowKey, visitId = match.visitId };
内容的提问来源于stack exchange,提问作者Alex Gordon
相关产品推荐
相关产品推荐

