我正在使用
JSON.Net来序列化DTO,我在物理设备上遇到以下异常.这适用于我们测试过的所有其他设备,但在运行版本4.2.2的三星Galaxy Tab 3lite SM-T110上失败了.
我有this issue但是当我升级到Xamarin 3.0时,它变成了以下内容:
06-03 21:17:41.687 E/mono-rt (22071): [ERROR] FATAL UNHANDLED EXCEPTION: System.TimeZoneNotFoundException: Exception of type 'System.TimeZoneNotFoundException' was thrown. 06-03 21:17:41.687 E/mono-rt (22071): at System.TimeZoneInfo.get_Local () [0x00000] in <filename unknown>:0 06-03 21:17:41.687 E/mono-rt (22071): at Newtonsoft.Json.Utilities.DateTimeUtils.GetUtcOffset (DateTime d) [0x00000] in <filename unknown>:0 06-03 21:17:41.687 E/mono-rt (22071): at Newtonsoft.Json.Utilities.DateTimeUtils.WriteDateTimeString (System.Char[] chars,Int32 start,DateTime value,Nullable`1 offset,DateTimeKind kind,DateFormatHandling format) [0x00000] in <filename unknown>:0 06-03 21:17:41.687 E/mono-rt (22071): at Newtonsoft.Json.JsonTextWriter.WriteValue (DateTime value) [0x00000] in <filename unknown>:0 06-03 21:17:41.687 E/mono-rt (22071): at Newtonsoft.Json.JsonWriter.WriteValue (Newtonsoft.Json.JsonWriter writer,PrimitiveTypeCode typeCode,System.Object value) [0x00000] in <filename unknown>:0 06-03 21:17:41.687 E/mono-rt (22071): at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializePrimitive (Newtonsoft.Json.JsonWriter writer,System.Object value,Newtonsoft.Json.Serialization.JsonPrimitiveContract contract,Newtonsoft.Json.Serialization. 06-03 21:17:41.695 I/mono-stdout(22071): Executing Command: UpdateRegistration The program 'Mono' has exited with code 0 (0x0).
编辑这是我试图序列化的DTO.您可以看到构造函数被调用的时间,它将其设置为DateTime.Now.难道这只是假设当地时区?
public class RecordTargetFrequency : BaseCommand,ICommand { public Guid TargetId { get; private set; } public Guid? LocationId { get; private set; } public Guid TherapistId { get; private set; } public bool? Increase { get; private set; } public DateTime TimeStamp { get; private set; } public RecordTargetFrequency(Guid targetId,Guid? locationId,Guid therapistId,bool? increase) { TimeStamp = DateTime.Now; TargetId = targetId; LocationId = locationId; TherapistId = therapistId; Increase = increase; } public void Validate() { ValidateGuid(TargetId); ValidateGuid(TherapistId); } }
然后我用这一行序列化它:
JsonConvert.SerializeObject(executedCommand);
解决方法
是的,TimeZoneInfo.Local在Mono上有所不同.我在这里看到了三种不同的故障模式:
>返回正确行动的时区,但ID为“Local”
>返回空引用
>抛出异常
我没有一个很好的解决方案,但如果你想记录一个时间戳,那么最好还是使用DateTime.UtcNow.那你根本不需要担心时区.在大多数情况下,您应该只是按时间存储和处理日期/时间值,而不关心时区甚至涉及哪个日历.
如果你可以从Java.Util.TimeZone.Default获得时区ID,你可以 – 你想在这里使用America / New_York – 那么另一个选择是使用我的Noda Time项目,其中包括IANA数据库.所以你可以创建一个ZonedDateTime来代表你所需要的.我们也支持Json.NET序列化,因此该部分不应成为问题.
但是,我鼓励你只使用UTC,除非你真的需要当地时间.
还有几个选项 – 您可能要考虑使用DateTimeOffset而不是DateTime;如果您只是尝试将值序列化为“具有UTC偏移的日期和时间”,那么DateTimeOffset.Now可能正是您想要的.
(如果这些都没有帮助,请提供更多关于您需要什么以及您希望JSON看起来像什么的背景信息.)