使用ServiceStack CsvSerializer时TimeSpan类型无法正确映射的问题
解决ServiceStack CsvSerializer序列化TimeSpan为ISO格式的问题
我明白你的困扰——ServiceStack的CsvSerializer默认会把TimeSpan序列化成ISO 8601的Duration格式(比如PT19H),而不是我们常用的hh:mm:ss格式。不用额外加字符串属性,ServiceStack本身就有优雅的解决方案,下面给你两种常用的方式:
1. 全局注册TimeSpan自定义序列化(推荐)
你可以通过CsvSerializer.AddTypeSerializer方法,全局配置TimeSpan类型的序列化和反序列化逻辑,这样所有TimeSpan属性都会统一使用你指定的格式:
// 建议在应用启动时注册一次,避免重复执行 CsvSerializer.AddTypeSerializer<TimeSpan>( // 序列化时将TimeSpan转为指定格式的字符串 timeSpan => timeSpan.ToString(@"hh\:mm\:ss"), // 反序列化时将字符串转回TimeSpan(如果需要导入CSV的话) inputStr => TimeSpan.Parse(inputStr) );
然后修改你的Convert方法(注意如果已经在启动时注册过,这里就不用重复注册了):
public string Convert() { var data = _table.Get(); CsvSerializer.UseEncoding = PclExport.Instance.GetUTF8Encoding(true); var csvStr = CsvSerializer.SerializeToCsv(data); return csvStr; }
如果你的TimeSpan可能包含天数(比如2.19:00:00),可以把格式字符串改成@"dd\:hh\:mm\:ss",根据你的需求调整即可。
2. 针对单个属性配置格式
如果你只想让某个类的特定TimeSpan属性使用自定义格式,可以使用ServiceStack的[Format]特性:
public class YourDataModel { // 其他属性... [Format(@"hh\:mm\:ss")] public TimeSpan YourTimeSpanProperty { get; set; } }
这个方式更灵活,适合只需要修改个别属性格式的场景。
补充说明
ServiceStack默认使用ISO 8601 Duration格式是因为它是国际标准,能准确表达时长信息,但在需要可读性更高的CSV场景下,自定义格式就很有必要了。上面两种方法都不需要额外添加冗余的字符串属性,是更符合ServiceStack设计理念的最优方案。
内容的提问来源于stack exchange,提问作者yertugrul
相关产品推荐
相关产品推荐

