[Mono-dev] [PATCH] Fix serialization of typed datasets

Nagappan Alagappan nagappan at gmail.com
Mon Sep 14 18:09:22 EDT 2009


Hello John,

This patch looks okay to me. Can you add the test case as well to this patch
?

Thanks
Nagappan

On Mon, Sep 14, 2009 at 12:48 PM, John Lenz <jlenz2 at math.uiuc.edu> wrote:

> This patch allows typed datasets produced by Microsoft's xsd.exe to work
> correctly in mono.  With this patch, I can serialize or deserialize the
> classes in the mono runtime and even communicate over
> the network where for example the client is running on mono and the
> server is running on MS.NET.
>
> I have only tested the XML serialization, I have not tested the binary
> serialization.  Thus my patch makes no changes to the code paths
> for binary serialization, but I suspect it actually fixes bug #427769
> because of the added call to InitializeDerivedDataSet in the constructor.
>
> Since these functions are undocumented, here is how I found out how they
> should work:  I looked at the code produced by xsd.exe and mono's
> implementation of the DataSet class.  Several things did not make sense
> until I made the changes below.  All are really obvious if you see what
> the xsd.exe produced code is expecting.
>
> I also ran a test server on the MS.NET runtime and a test client in
> monodevelop on the mono runtime.  I stuck some breakpoints into the
> client using monodevelop to see what the serialization format looked like.
>
> Here are the changes:
>
> 1) The GetSerializationData() function should only load the data, not
> the schema.  This function is called by the derived dataset constructor
> after it has loaded the schema.  So I moved the schema loading code out
> of GetSerializationData and into the constructor.
>
> 2) We need to know the incoming serialization mode (Included or Excluded).
> This is serialized in the "SchemaSerializationMode.DataSet", which I found
> using monodevelop to debug the client constructor.  Fix the
> DetermineSchemaSerializationMode function and add the parameter to the
> serialization code.
>
> 3) Implement the DataSet(SerializationInfo, StreamingContext, bool)
> constructor.  Basically, if the schema is excluded we call
> InitializeDerivedDataSet to create it.  This is really weird and
> I have no idea why the derived class does not call it directly.
> But the xsd.exe generated code expects it is called from the
> constructor.  The InitializeDerivedDataSet
> function in the base class should do nothing, it is overridden in each
> typed dataset.
>
> Index: class/System.Data/System.Data/DataSet.cs
> ===================================================================
> --- class/System.Data/System.Data/DataSet.cs    (revision 141910)
> +++ class/System.Data/System.Data/DataSet.cs    (working copy)
> @@ -95,6 +95,17 @@
>                protected DataSet (SerializationInfo info, StreamingContext
> context)
>                        : this ()
>                {
> +#if NET_2_0
> +                       if (IsBinarySerialized (info, context)) {
> +                               BinaryDeserialize (info);
> +                               return;
> +                       }
> +#endif
> +                       string s = info.GetValue ("XmlSchema", typeof
> (String)) as String;
> +                       XmlTextReader reader = new XmlTextReader (new
> StringReader (s));
> +                       ReadXmlSchema (reader);
> +                       reader.Close ();
> +
>                        GetSerializationData (info, context);
>                }
>
> @@ -1132,6 +1143,9 @@
>                {
>  #if NET_2_0
>                        if (RemotingFormat == SerializationFormat.Xml) {
> +
> +                               info.AddValue
> ("SchemaSerializationMode.DataSet", this.SchemaSerializationMode);
> +
>  #endif
>                                StringWriter sw = new StringWriter ();
>                                XmlTextWriter writer = new XmlTextWriter
> (sw);
> @@ -1155,19 +1169,8 @@
>                #region Protected Methods
>                protected void GetSerializationData (SerializationInfo info,
> StreamingContext context)
>                {
> -#if NET_2_0
> -                       if (IsBinarySerialized (info, context)) {
> -                               BinaryDeserialize (info);
> -                               return;
> -                       }
> -#endif
> -                       string s = info.GetValue ("XmlSchema", typeof
> (String)) as String;
> +                       string s = info.GetValue ("XmlDiffGram", typeof
> (String)) as String;
>                        XmlTextReader reader = new XmlTextReader (new
> StringReader (s));
> -                       ReadXmlSchema (reader);
> -                       reader.Close ();
> -
> -                       s = info.GetValue ("XmlDiffGram", typeof (String))
> as String;
> -                       reader = new XmlTextReader (new StringReader (s));
>                        ReadXml (reader, XmlReadMode.DiffGram);
>                        reader.Close ();
>                }
> @@ -1547,10 +1550,26 @@
>                private bool dataSetInitialized = true;
>                public event EventHandler Initialized;
>
> -               [MonoTODO]
>                protected DataSet (SerializationInfo info, StreamingContext
> context, bool constructSchema)
> -                       : this (info, context)
> +                       : this ()
>                {
> +                       if (DetermineSchemaSerializationMode (info,
> context) == SchemaSerializationMode.ExcludeSchema) {
> +                               InitializeDerivedDataSet ();
> +                       }
> +
> +                       if (IsBinarySerialized (info, context)) {
> +                               BinaryDeserialize (info);
> +                               return;
> +                       }
> +
> +                       if (constructSchema) {
> +                               string s = info.GetValue ("XmlSchema",
> typeof (String)) as String;
> +                               XmlTextReader reader = new XmlTextReader
> (new StringReader (s));
> +                               ReadXmlSchema (reader);
> +                               reader.Close ();
> +
> +                               GetSerializationData (info, context);
> +                       }
>                }
>
>                SerializationFormat remotingFormat =
> SerializationFormat.Xml;
> @@ -1751,10 +1770,8 @@
>                        OnDataSetInitialized (e);
>                }
>
> -               [MonoTODO]
>                protected virtual void InitializeDerivedDataSet ()
>                {
> -                       throw new NotImplementedException ();
>                }
>
>                protected SchemaSerializationMode
> DetermineSchemaSerializationMode (XmlReader reader)
> @@ -1764,6 +1781,13 @@
>
>                protected SchemaSerializationMode
> DetermineSchemaSerializationMode (SerializationInfo info, StreamingContext
> context)
>                {
> +                       SerializationInfoEnumerator e = info.GetEnumerator
> ();
> +                       while (e.MoveNext ()) {
> +                               if (e.Name ==
> "SchemaSerializationMode.DataSet") {
> +                                       return (SchemaSerializationMode)
> e.Value;
> +                               }
> +                       }
> +
>                        return SchemaSerializationMode.IncludeSchema;
>                }
>
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>



-- 
Linux Desktop (GUI Application) Testing Project -
http://ldtp.freedesktop.org
http://nagappanal.blogspot.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20090914/9e06f6dd/attachment-0001.html 


More information about the Mono-devel-list mailing list