2016-03-03 1 views
0

J'ai un petit problème - La désérialisation XML ignore complètement les éléments qui ne sont pas dans l'ordre alphabétique. Dans l'exemple d'objet (description à la fin de la question), le noeud Birthday est après le noeud FirstName, et il est ignoré et la valeur par défaut est attribuée après la désérialisation. Idem pour tous les autres types et noms (j'avais le noeud CaseId de Guid type après le noeud Patient de type PatientInfo, et après désérialisation il avait la valeur par défaut).La désérialisation XML ignore les propriétés par ordre alphabétique

Je sérialisation dans une application, en utilisant le code suivant:

public static string SerializeToString(object data) 
{ 
    if (data == null) return null; 
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); 
    ns.Add("", ""); 

    // what should the XmlWriter do? 
    var settings = new XmlWriterSettings 
    { 
     OmitXmlDeclaration = true, 
     NewLineChars = "" 
    }; 

    using (var stringwriter = new System.IO.StringWriter()) 
    { 
     // Use an XmlWriter to wrap the StringWriter 
     using (var xmlWriter = XmlWriter.Create(stringwriter, settings)) 
     { 
      var serializer = new XmlSerializer(data.GetType(), ""); 
      // serialize to the XmlWriter instance 
      serializer.Serialize(xmlWriter, data, ns); 
      return stringwriter.ToString(); 
     } 
    } 
} 

Cette approche a été utilisée pour obtenir le résultat correct comme argument pour WebMethod (problème complet décrit here). Les résultats sont quelque chose comme ceci:

< PatientInfo> < FirstName> Foo </FirstName> < Birthday> 2015-12-19T16: 21: 48,4009949 + 01: 00 </Anniversaire> < RequestedClientID> 00000000-0000- 0000-0000-000000000000 </RequestedClientID> 00000000-0000-0000-0000-000000000000 </patientId> </PatientInfo>

Je suis aussi désérialisation dans une autre application de manière simple

public static T Deserialize<T>(string xmlText) 
{ 
    if (String.IsNullOrEmpty(xmlText)) return default(T); 
    using (var stringReader = new StringReader(xmlText)) 
    { 
     var serializer = new XmlSerializer(typeof(T)); 
     return (T)serializer.Deserialize(stringReader); 
    } 
} 

Exemple objet:

[XmlRoot("PatientInfo")] 
public class PatientInfo 
{ 
    [XmlElement("FirstName")] 
    public string FirstName { get; set; } 
    [XmlElement("LastName")] 
    public string LastName { get; set; } 
    [XmlElement("SSN")] 
    public string SSN { get; set; } 
    [XmlElement("Birthday")] 
    public DateTime? Birthday { get; set; } 
    [XmlElement("RequestedClientID")] 
    public Guid RequestedClientID { get; set; } 
    [XmlElement("patientId")] 
    public Guid patientId { get; set; } 
} 

Donc, j'aimerais avoir réponse à l'une des deux questions - 1) Comment puis-je ajuster mon sérialisation d'avoir tous les éléments dans l'ordre alphabétique? 2) Comment puis-je ajuster ma désérialisation pour ne pas ignorer les éléments par ordre alphabétique?

Toute aide est appréciée.

Mise à jour:

Tout compris, cette méthode de désérialisation J'utilise est pas vraiment utilisé du tout dans mon problème, puisque je suis en utilisant les informations sérialisé en tant que données avec WebMethod, et il est désérialisée avec un mécanisme interne de WCF.

+0

Il semble, de cette façon simple de mettre toutes les propriétés en classe d'objets dans l'ordre, mais je serais plutôt agacé de chercher la place appropriée pour chaque nouvelle propriété que j'ajoute à la classe. – lentinant

+0

Je ne peux pas reproduire votre problème. Si j'inverse l'ordre des nœuds dans le XML, il est néanmoins désérialisé avec succès. Voir https://dotnetfiddle.net/xN5PSk – dbc

+0

@dbc En fait, il semble que j'ai fait une fausse déclaration, et le fait que cela soit utilisé avec la méthode Web est beaucoup plus important que je ne le pensais. En fait, la seconde application reçoit des données dans Web Method, et elle est désérialisée avec un mécanisme interne, donc ma méthode de désérialisation n'a rien à voir avec ça. Désolé pour la désinformation = ( – lentinant

Répondre

1

WCF uses DataContractSerializer. Ce sérialiseur est sensible à l'ordre des éléments XML, voir Data Member Order. Il n'y a pas de moyen rapide pour , à la place vous devez remplacer le sérialiseur par XmlSerializer.

Pour ce faire, voir Using the XmlSerializer Class, puis et appliquer [XmlSerializerFormat] à votre service, par exemple:

[ServiceContract] 
[XmlSerializerFormat] 
public interface IPatientInfoService 
{ 
    [OperationContract] 
    public void ProcessPatientInfo(PatientInfo patient) 
    { 
     // Code not shown. 
    } 
} 

[XmlRoot("PatientInfo")] 
public class PatientInfo 
{ 
    [XmlElement("FirstName")] 
    public string FirstName { get; set; } 
    [XmlElement("LastName")] 
    public string LastName { get; set; } 
    [XmlElement("SSN")] 
    public string SSN { get; set; } 
    [XmlElement("Birthday")] 
    public DateTime? Birthday { get; set; } 
    [XmlElement("RequestedClientID")] 
    public Guid RequestedClientID { get; set; } 
    [XmlElement("patientId")] 
    public Guid patientId { get; set; } 
}