我正在将一个库从.net框架4.7迁移到.net核心2.2,并发现深度对象克隆的一个问题,我在下面缩小到了一个简短的可重复代码片段。
你自己试试吧:
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace Test
{
public class Program
{
public static void Main(string[] args)
{
// any zone here, don't care what it is
var zone = TimeZoneInfo.GetSystemTimeZones()[0];
var formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
formatter.Serialize(stream, zone);
stream.Seek(0, SeekOrigin.Begin);
var result = formatter.Deserialize(stream);
Console.WriteLine("all ok");
}
}
}
}在使用.net核心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中使用TimeZoneInfo内核2.2中的二进制序列化?
发布于 2019-08-26 16:57:06
实际上,这似乎是一种小虫子。感谢您提出的问题所在。
然而,从你的评论看,似乎有一个简单的解决办法。与其序列化TimeZoneInfo,不如将对象更改为只序列化ID。如果您愿意的话,您可以在它周围放置一个带有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自动属性后面的字符串才会被序列化/反序列化。在序列化/反序列化期间,TimeZoneInfo将被忽略,并且只在您自己的代码中访问对象时使用。
https://stackoverflow.com/questions/57655469
复制相似问题