c# – Xamarin.Android JSON.Net serilization在4.2.2设备上失败只有TimeZoneNotFound异常

我正在使用 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看起来像什么的背景信息.)

相关文章

目录简介使用JS互操作使用ClipLazor库创建项目使用方法简单测...
目录简介快速入门安装 NuGet 包实体类User数据库类DbFactory...
本文实现一个简单的配置类,原理比较简单,适用于一些小型项...
C#中Description特性主要用于枚举和属性,方法比较简单,记录...
[TOC] # 原理简介 本文参考[C#/WPF/WinForm/程序实现软件开机...
目录简介获取 HTML 文档解析 HTML 文档测试补充:使用 CSS 选...