Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataContractSerializer not deserializing references

I am using the DataContractSerializer in .NET 3.5 to deserialize xml. The xml was previously serialized from a group of related entities in an entity model, backed by the entity framework 3.5. There are many references, and the xml extensively contains all the values of the members and keys of each referenced entity.

The top level entity deserializes fine, but the referenced entities do not.

This is the code I'm using to serialize and deserialize:

    public static T DCDeserializeXml<T>(string xml)
    {
        MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(xml));
        using (
        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.Unicode,
                   new XmlDictionaryReaderQuotas(), null))
        {
            DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T), null, Int32.MaxValue, false, true, null);
            return (T)dataContractSerializer.ReadObject(reader, true);
        }
    }

    public static string DCSerializeToXml<T>(T obj)
    {
        DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T), null, Int32.MaxValue, false, true, null);

        String text;
        using (MemoryStream memoryStream = new MemoryStream())
        {
            dataContractSerializer.WriteObject(memoryStream, obj);                
            byte[] data = new byte[memoryStream.Length];
            Array.Copy(memoryStream.GetBuffer(), data, data.Length);
            text = Encoding.UTF8.GetString(data);
        }
        return text;
    }

This is a snippet of the XML:

<?xml version="1.0" encoding="utf-8"?>
<Assets>
    <Asset z:Id="i1" xmlns="http://schemas.datacontract.org/2004/07/XLayer" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
        <EntityKey z:Id="i2" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data">
            <a:EntityContainerName>XModelContainer</a:EntityContainerName>
            <a:EntityKeyValues>
                <a:EntityKeyMember>
                    <a:Key>AssetGUID</a:Key>
                    <a:Value i:type="z:guid">7424f615-43db-4834-b15a-5befa46bfd55</a:Value>
                    </a:EntityKeyMember></a:EntityKeyValues>
                    <a:EntitySetName>AssetSet</a:EntitySetName>
                    </EntityKey>
                    <AssetGUID>7424f615-43db-4834-b15a-5befa46bfd55</AssetGUID>
                    <Created>2011-06-23T13:34:12.893</Created>
                    <Description/>
                    <npAudioInfoReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses">
                        <a:EntityKey i:nil="true" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data"/>
                    </npAudioInfoReference>
                    <npCampaigns/>
                    <npCategory z:Id="i3">
                        <EntityKey z:Id="i4" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data">
                            <a:EntityContainerName>XModelContainer</a:EntityContainerName>
                            <a:EntityKeyValues>
                                <a:EntityKeyMember>
                                    <a:Key>CategoryID</a:Key>
                                    <a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema">1</a:Value>
                                </a:EntityKeyMember>
                            </a:EntityKeyValues>
                            <a:EntitySetName>AssetCategorySet</a:EntitySetName>
                        </EntityKey>
                        <AM_DataDocumentTypes/>
                        <CategoryID>1</CategoryID>
                        <CategoryName>Generic Content</CategoryName>
                        <npAssets>

I've been stuck on this for a couple days and I've exhausted all search results that I could find. Using this technique can clearly avoid hand writing tons of code for each entity type in our model, of which there are 143.

So to reiterate, the top level entity deserializes fine, but the referenced entities do not. So Asset is loaded and Asset.AssetCategory (among many more) resolves to null after deserialization, and I need help to fix it so all references get instantiated. Please, anyone?

like image 538
Jack Avatar asked Nov 05 '22 18:11

Jack


1 Answers

Sometimes you need to tell the serializer about other "Known Types".

See the MSDN documentation:

http://msdn.microsoft.com/en-us/library/ms730167.aspx

You can do this through the config, through attributes, or through parameters/a property on DataContractSerializer.

There is a full example the documentation links to here:

http://msdn.microsoft.com/en-us/library/ms751512.aspx

like image 124
Steve Avatar answered Nov 15 '22 05:11

Steve