2011-07-05 2 views
5

J'utilise DataContractSerializer dans .NET 3.5 pour désérialiser xml. Le fichier XML a été précédemment sérialisé à partir d'un groupe d'entités associées dans un modèle d'entité, soutenu par l'infrastructure de l'entité 3.5. Il existe de nombreuses références, et le fichier xml contient de manière exhaustive toutes les valeurs des membres et des clés de chaque entité référencée.DataContractSerializer ne désérialisant pas les références

L'entité de premier niveau se désérialise correctement, contrairement aux entités référencées.

C'est le code que je utilise pour sérialiser et désérialiser:

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

Ceci est un extrait du 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> 

Je suis coincé sur ce pendant deux jours et j'ai épuisé tous les résultats de recherche que j'ai pu trouver. L'utilisation de cette technique permet clairement d'éviter d'écrire à la main des tonnes de code pour chaque type d'entité dans notre modèle, dont il existe 143.

Donc, pour réitérer, l'entité de premier niveau se désérialise bien, mais pas les entités référencées. Donc Asset est chargé et Asset.AssetCategory (parmi beaucoup d'autres) se résout à null après la désérialisation, et j'ai besoin d'aide pour le réparer afin que toutes les références soient instanciées. S'il vous plaît, n'importe qui?

+2

Check out "KnownTypes" – Steve

Répondre

2

Parfois, vous devez indiquer au sérialiseur les autres "types connus".

Voir la documentation MSDN:

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

Vous pouvez le faire à travers la config, par des attributs, ou par des paramètres/une propriété sur DataContractSerializer.

Il y a un exemple complet les liens de documentation à ici:

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

+0

Cela semble prometteur. Je vais essayer le matin. Très apprécié. – Jack

+0

Pas un problème :) Faites-moi savoir comment cela fonctionne pour vous. – Steve

Questions connexes