C# 在Linux上反序列化TimeZoneInfo时,Month参数必须在1到12之间`

C# 在Linux上反序列化TimeZoneInfo时,Month参数必须在1到12之间`,c#,.net,serialization,.net-core,timezone,C#,.net,Serialization,.net Core,Timezone,我正在将一个库从.NETFramework4.7迁移到.NETCore2.2,发现了一个问题,我将其缩小到下面一个简短的可复制代码段 你自己试试这个: (通过) (失败) 在使用.net core 2.2的Windows平台上,这可以正常工作,但在Linux平台上有一个例外: Unhandled Exception: System.Runtime.Serialization.SerializationException: An error occurred while deserializi

我正在将一个库从.NETFramework4.7迁移到.NETCore2.2,发现了一个问题,我将其缩小到下面一个简短的可复制代码段

你自己试试这个:

  • (通过)
  • (失败)
在使用.net core 2.2的Windows平台上,这可以正常工作,但在Linux平台上有一个例外:

Unhandled Exception: System.Runtime.Serialization.SerializationException: An error occurred while deserializing the object.  The serialized data is corrupt. ---> System.ArgumentOutOfRangeException: The Month parameter must be in the range 1 through 12.
Parameter name: month
   at System.TimeZoneInfo.TransitionTime.ValidateTransitionTime(DateTime timeOfDay, Int32 month, Int32 week, Int32 day, DayOfWeek dayOfWeek)
   at System.TimeZoneInfo.TransitionTime.System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(Object sender)
   --- End of inner exception stack trace ---
   at System.TimeZoneInfo.TransitionTime.System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(Object sender)
   at System.Runtime.Serialization.ObjectManager.RaiseDeserializationEvent()
   at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(BinaryParser serParser, Boolean fCheck)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, Boolean check)
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
   at Test.Program.Main(String[] args)

问题:在Linux的.net core 2.2中,如何在
TimeZoneInfo
中使用二进制序列化?

确实,这看起来像是一个bug。谢谢你的提高

然而,从你的评论来看,似乎有一个简单的解决办法。将对象更改为仅序列化ID,而不是序列化
TimeZoneInfo
。如果愿意,可以在对象周围放置一个带有get/set访问器的属性,以方便使用

例如,而不是:

public class Foo
{
    public TimeZoneInfo TimeZone { get; set; }
}
您可以这样做:

public class Foo
{
    public string TimeZoneId { get; set; }

    public TimeZoneInfo TimeZone
    {
        get => TimeZoneInfo.FindSystemTimeZoneById(TimeZoneId);
        set => TimeZoneId = value.Id;
    }
}

BinaryFormatter
仅序列化字段,因此只有隐藏在
TimeZoneId
auto属性后面的字符串将被序列化/反序列化。
TimeZoneInfo
在序列化/反序列化期间将被忽略,仅在您自己的代码中访问对象时使用。

在.Net Core 2.1中尝试时,这一功能有效(我没有安装2.2)。它在2.1版中对你有效吗?刚刚尝试过这个,它在.NETCore2.2版中对我有效…@MatthewWatson-这在基于Linux的环境中对你有效吗?正如OP所发布的,它可以在Windows上正常工作,但不能在基于Linux的系统上工作。您是否尝试进行干净的构建?升级后可能无法重新生成代码。检查项目bin文件夹(release和debug)中可执行文件的日期时间。对于感兴趣的任何人,我已将此问题报告给.net core repo
public class Foo
{
    public string TimeZoneId { get; set; }

    public TimeZoneInfo TimeZone
    {
        get => TimeZoneInfo.FindSystemTimeZoneById(TimeZoneId);
        set => TimeZoneId = value.Id;
    }
}