2011-10-09 14 views
7

Tengo un pequeño problema al serializar el objeto TimeZoneInfo. Estaba intentando usar la variable TimeZoneInfo en el contrato de datos para el servicio WCF, pero la serialización estaba fallando. Así que escribí este pequeño fragmento de código para probar la serialización. Aquí hay una lo que hago:C# serialización 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); 
     } 

Ahora, cuando llamo WriteObject método lanza una excepción:

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.

si intento agregar [KnownType (typeof (System.TimeZoneInfo.AdjustmentRule []))]] a la clase me sale el mismo error. Y si puedo añadir esta línea a la interfaz de mi contrato de datos me sale error de compilación:

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

y de acuerdo a la clase de documentación TimeZoneInfo implementa ISerializable por lo que debe serializar de forma predeterminada.

¿Alguien puede decirme qué estoy haciendo mal aquí? Apreciaría cualquier ayuda.

Gracias.

Respuesta

6

No estoy seguro de por qué no se serializa simplemente, pero ¿ha considerado simplemente serializar el ID? Es probable que sea bastante más eficiente, ¡y más simple! - que serializar toda la información interna, y debería estar bien siempre y cuando ambos sistemas tengan esa zona horaria.

EDITAR: tenga en cuenta que esto no funcionará con zonas horarias personalizadas, para lo cual debe mirar ToSerializedString como se indica en otros lugares.

+1

Sí, es decir como un trabajo en torno a que tendría que hacer algo por el estilo. Pero me gustaría que la variable sea fuerte y, en general, estoy algo desconcertado sobre por qué esto no funciona. ¿De qué sirve que la clase sea ISerializable si no puedo serializarla? – RedOctober

+1

@RedOctober: No lo sé, eso parece extraño. No sé lo suficiente sobre WCF para saber si DataContractSerializer usa el mismo formato que el BinarySerializer normal, que es I * believe * de lo que se trata ISerializable. Tenga en cuenta que si serializa solo la ID, cuando vuelva a buscar la zona horaria obtendrá la información más actualizada del sistema operativo, en lugar de solo lo que se sabía en el momento de la serialización. Si esto es algo bueno o no depende de tu situación exacta, por supuesto. –

+1

1. El comportamiento se ve como un error en el marco. 2. La identificación no sería suficiente cuando obtiene la zona horaria personalizada. Usé el método ToSerializedString como solución. (http://msdn.microsoft.com/en-us/library/system.timezoneinfo.toserializedstring(v=vs.100).aspx) –

1

No estoy seguro de por qué tampoco. Como Jon sugirió una propiedad proxy con la identificación, probablemente sea el camino a seguir.

Alternativamente, si realmente necesita transmitir el contenido de TimeZoneInfo y admitir zonas personalizadas, debe usar una propiedad proxy que ajuste ToSerializedString() y FromSerializedString().