【问题标题】:c# TimeZoneInfo serializationc# TimeZoneInfo 序列化
【发布时间】:2011-10-09 16:33:55
【问题描述】:

我在序列化 TimeZoneInfo 对象时遇到了一点问题。我试图在 WCF 服务的数据合同中使用 TimeZoneInfo 变量,但序列化失败。所以我写了一小段代码来测试序列化。这是我的工作:

        var fileName = "tmp.xml";
        var tz = TimeZoneInfo.Local;
        var dataSer = new DataContractSerializer(typeof(TimeZoneInfo));

        try
        {
            using (var xml = new FileStream(fileName, FileMode.Create))
            {
                dataSer.WriteObject(xml, tz);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

现在,当我调用 WriteObject 方法时,它会引发异常:

不应使用数据合同名称“ArrayOfTimeZoneInfo.AdjustmentRule:http://schemas.datacontract.org/2004/07/System”键入“System.TimeZoneInfo+AdjustmentRule[]”。考虑使用 DataContractResolver 或将任何静态未知的类型添加到已知类型列表中 - 例如,通过使用 KnownTypeAttribute 属性或将它们添加到传递给 DataContractSerializer 的已知类型列表中。

如果我尝试添加 [KnownType(typeof(System.TimeZoneInfo.AdjustmentRule[]))] 到类我得到同样的错误。如果我将此行添加到我的数据合约接口中,我会收到编译错误:

错误 1 ​​'System.TimeZoneInfo.AdjustmentRule' 由于其保护级别而无法访问

并且根据文档 TimeZoneInfo 类实现 ISerializable 所以它应该默认序列化。

谁能告诉我我在这里做错了什么?我将不胜感激。

谢谢。

【问题讨论】:

    标签: c# wcf serialization timezone


    【解决方案1】:

    我不知道为什么它不只是简单地序列化,但您是否考虑过只序列化ID?这可能会更有效 - 更简单! - 而不是序列化里面的所有信息,只要两个系统都有那个时区就应该没问题。

    编辑:请注意,这不适用于自定义时区,您应该查看ToSerializedString,如其他地方所述。

    【讨论】:

    • 是的,我的意思是作为一种解决方法,我必须做一些类似的事情。但是我想对变量进行强类型化,总的来说,我对为什么这不起作用感到有些困惑。如果我不能序列化,那么 ISerializable 类的意义何在?
    • @RedOctober:我不知道——这看起来很奇怪。我对 WCF 的了解不够,无法知道 DataContractSerializer 是否使用与普通 BinarySerializer 相同的格式,我 相信 ISerializable 是关于什么的。请注意,如果您仅序列化 ID,那么当您再次获取时区时,您将从操作系统获得最新信息,而不仅仅是序列化时已知的信息。当然,这是否是一件好事取决于您的具体情况。
    • 1.该行为看起来像框架中的错误。 2. 当您获得自定义时区时,ID 是不够的。我使用 ToSerializedString 方法作为解决方法。 (msdn.microsoft.com/en-us/library/…)
    • @PuterdoBorato:是的,但我怀疑大多数程序会使用自定义时区,是吗? (不过我应该提到这一点。)
    • @JonSkeet 你说得对,ISerializable 是 BinarySerializer,而不是 DataContractSerializer。开箱即用的 WCF 不完全支持这些类型。您可以在声明或发送包含 DateTime 和 Offset(以秒为单位)的客户对象时转换为字符串。如果具有 WSDL 访问权限的客户端没有将类型正确地解释为 UTC,这可能会出现问题。这就是为什么我觉得您的“字符串”解决方案可能是一个更安全的选择,因为您可以在另一端解析数据。如果您可以完全控制前端(例如 MVC),则可以执行“OnDeserialized”。
    【解决方案2】:

    我也不知道为什么。正如 Jon 建议的那样,带有 ID 的代理属性可能是可行的方法。

    或者,如果您确实需要传输 TimeZoneInfo 的内容并支持自定义区域,则应使用包装 ToSerializedString()FromSerializedString() 的代理属性。

    【讨论】:

      【解决方案3】:

      看起来 TimeZoneInfo 不能很好地与 WCF 一起使用。 解决方法可以在这里找到:

      http://social.msdn.microsoft.com/Forums/en/wcf/thread/f164f185-ae18-4775-a2ff-a814813d262d

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-12
        • 2011-05-12
        • 1970-01-01
        • 1970-01-01
        • 2014-12-30
        • 2012-02-02
        • 2016-06-15
        • 2010-11-25
        相关资源
        最近更新 更多