7
votes

I'm have a bit of a problem with serializing TimeZoneInfo object. I was trying to use TimeZoneInfo variable in data contract for WCF service but the serialization was failing. So i wrote this little piece of code to test the serialization. Here's a what i do:

        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);
        }

Now, when i call WriteObject method it throws an exception:

Type 'System.TimeZoneInfo+AdjustmentRule[]' with data contract name 'ArrayOfTimeZoneInfo.AdjustmentRule:http://schemas.datacontract.org/2004/07/System' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

If i attempt to add [KnownType(typeof(System.TimeZoneInfo.AdjustmentRule[]))] to the class i get the same error. And if i add this line to my data contract interface i get compile error:

Error 1 'System.TimeZoneInfo.AdjustmentRule' is inaccessible due to its protection level

And according to the documentation TimeZoneInfo class implements ISerializable so it should serialize by default.

Can anyone tell me what i'm doing wrong here? I would appreciate any help.

Thanks.

3

3 Answers

6
votes

I'm not sure why it doesn't just serialize simply, but have you considered just serializing the ID? That's likely to be rather more efficient - and simpler! - than serializing all the information inside, and should be fine so long as both systems have that time zone.

EDIT: Note that this won't work with custom time zones, for which you should look at ToSerializedString as noted elsewhere.

1
votes

I'm not sure why either. As Jon suggested a proxy property with the ID is the probably the way to go.

Alternatively, if you actually need to transmit the content of the TimeZoneInfo and support custom zones, you should use a proxy property that wraps ToSerializedString() and FromSerializedString().

0
votes

Looks like TimeZoneInfo does not work with WCF very well out-of-the-box. The workaround can be found here:

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