TheChaseMan's Frenetic SoapBox

Always looking for better ways to do things...

XmlSerializer, XmlCustomFormatter, XmlSerializationWriter.FromDateTime, XmlConvert issue

 
Like the really, really long post title? :-)
 
Anyway, so the problem with the date containing the time zone offset is the internal class XmlCustomFormatter that has a FromDateTime method that calls XmlConvert.ToString with a hard-coded format value that has the "zzzzzz" on the end. FromDateTime is called by the autogenerated derived class code from the base class System.Xml.Serialization.XmlSerializationWriter.
 
internal static string FromDateTime(DateTime value) {
    return XmlConvert.ToString(value, "yyyy-MM-ddTHH:mm:ss.fffffffzzzzzz");
}
 
What you can do is:
 
1. create a Console app.

using
System.Xml.Serialization;
using System;

namespace
XmlSerializationDemo {
    public class
Movie {
       
public Movie() {}
       
public Movie(DateTime openingDate, string name){
           
this.OpeningDate = openingDate;
           
this.Name = name;
       
}
       
public DateTime OpeningDate;
       
public string Name;
   
}

    public class ConsoleApp {
       
[STAThread]
        static 
void Main(string
[] args) {
           
Movie movie =
new Movie(new DateTime(2004, 5, 26), "Rocky 1000000");
            XmlSerializer serializer = new XmlSerializer(typeof(Movie));
            serializer.Serialize(Console.Out, movie);

     
   }
    }
}
2. Create an App.config file to go with it. This will contain a switch that tells the compiler to keep the Serialization code that gets autogenerated.

<?

xml version="1.0" encoding="utf-8" ?>
    <
configuration
>
     
<system.diagnostics
>
        
<switches
>
           
<add name="XmlSerialization.Compilation" value="4"
/>
        
</switches
>
    
</system.diagnostics
>
</
configuration>
3. Compile and run the app.
 
    You can see that the date gets serialized with the timezone info.
 
4. Go to the C:\Documents and Settings\\Local Settings\Temp folder and you will find an ouput file. Mine was a .CS, but if you do it in VB there's probably a VB file.
 
5. Copy that class code into new class file you add to your project.
 
6. Make the void Write1_Movie method public.
 
7. You can modify the Write1_Movie code so it serializes your custom object the way you want. In this example, I'm changing the DateTime output so that it does not have the timezone offset info:
 

public void Write1_Movie(string n, string ns, XmlSerializationDemo.Movie o, bool isNullable, bool needType) {
   
if ((object)o == null) {
       
if (isNullable) WriteNullTagLiteral(n, ns);
           
return;
       
}
   
if (!needType) {
       
System.Type t = o.GetType();
       
if (t == typeof(XmlSerializationDemo.Movie));
       
else {
           
throw CreateUnknownTypeException(o);
       
}
    }

    //Must set the Writer for output. You could make this a function parameter...
   
this.Writer = new System.Xml.XmlTextWriter(System.Console.Out);
   
WriteStartElement(n, ns, o);
   
if (needType) WriteXsiType(@"Movie", @"");
    
//Change the FromDateTime
    
//WriteElementStringRaw(@"OpeningDate", @"", FromDateTime(((System.DateTime)o.@OpeningDate)));
    
string myCustomDateTimeSer = System.Xml.XmlConvert.ToString(o.@OpeningDate, "yyyy-MM-ddTHH:mm:ss.fffffff");
    
WriteElementStringRaw(@"OpeningDate", @"", myCustomDateTimeSer);
    
WriteElementString(@"Name", @"", ((System.String)o.@Name));
    
WriteEndElement(o);
}

This is kind of a simple example, but if you wanted to extend it, you could pass in an object to assign to the Writer because clearly you aren't going to be writing console apps to output your XML. However, it's not a bad start. Hopefully there will be future extensions in the .NET BCL that will give you the ability to have more control of the XML serializer data type formatting.
 
You can download the source code at http://www.unboxedsolutions.com/sean/files/XmlSerializationDemo.zip if you are interested.

Digg!

posted on Saturday, March 13, 2004 11:09 AM

Feedback

# re: XmlSerializer, XmlCustomFormatter, XmlSerializationWriter.FromDateTime, XmlConvert issue 5/21/2004 8:19 AM John Brown

This is a big problem. I 'm serializing my DataSet's using .Net Remoting and this bug is causing a date and time shift on all of my date fields due to the changes in time zone. I was going to write a SurrogateSelector and SerializationSurrogate but that does not seem able to work. Do you know how to integrate your solution into the remoting layer?