2016-06-03 6 views
2

deserialisieren Wenn die Datacontract Serializer verwenden, schlägt er den Id Wert, wie in der folgenden Probe deserialisieren:Datacontract nicht Id Datamember

using System; 
using System.Runtime.Serialization; 
using System.Xml.Linq; 

public class Program 
{ 
    private const string SAMPLE_VALIDATION_RESULT_XML = @" <ValidationResult> 
     <Message>The FooBar record has duplicate key values.</Message> 
     <Id>Microsoft.LightSwitch.EntityObject.DuplicateKey</Id> 
     <Target>http://localhost:55815/ApplicationData.svc/FooBar(0)</Target> 
    </ValidationResult>"; 

    [DataContract(Name = "ValidationResult", Namespace = "")] 
    public class ValidationResult 
    { 
     [DataMember] 
     public string Message { get; set; } 
     [DataMember] 
     public string Id { get; set; } 
     [DataMember] 
     public string Target { get; set; } 
    } 


    public static void Main() 
    { 
     var doc = XDocument.Parse(SAMPLE_VALIDATION_RESULT_XML); 
     using (var reader = doc.CreateReader()) 
     { 
      reader.MoveToContent(); 
      var res = (new DataContractSerializer(typeof(ValidationResult))).ReadObject(reader) as ValidationResult; 
      Console.WriteLine($"res.Id = \"{res.Id}\", expected \"Microsoft.LightSwitch.EntityObject.DuplicateKey\""); 
     } 
    } 
} 

Ich vermute, es mit den Referenzintegritätsfunktionen zu tun ist, aber Ich habe nur eine Option gefunden, um das zu deaktivieren (auf dem DataContractSerializer), und es hat das Ergebnis nicht beeinflusst.

Ich kann den Namen des Feldes Id nicht ändern, da es sich um eine API eines Drittanbieters handelt. Wie kann ich also auf diesen Wert zugreifen?

+1

Dieser Code 'ReadObject (Leser) als ValidationResult' gilt als schlechte Form. Da Sie wissen, dass es immer ein 'ValidationResult' sein wird, sollten Sie einen expliziten Cast verwenden. –

Antwort

3

Festlegen der Reihenfolge der Mitglieder

[DataContract(Name = "ValidationResult", Namespace = "")] 
public class ValidationResult 
{ 
    [DataMember(Order = 0)] 
    public string Message { get; set; } 
    [DataMember(Order = 1)] 
    public string Id { get; set; } 
    [DataMember(Order = 2)] 
    public string Target { get; set; } 
} 

ohne Befehl spezifiziert erwartet der DataContractSerializer die Mitglieder in alphabetischer Reihenfolge sind. Siehe Basic rules. Es ist offensichtlich, dass die Bestellung von dem Dienstleister festgelegt wurde. Sie müssen es also angeben.

+0

Das scheint etwas fragil - ich weiß nicht genau, ob der API-Provider sie immer in der richtigen Reihenfolge zurückgibt. –

+0

@ LiamDawson - siehe Update. Entschuldigung für mein schlechtes Englisch. –

+0

Ugh, das ist scheiße. Ich bin überrascht, dass sie diese Einschränkung hinzugefügt haben. –

1

Verwenden Sie diese stattdessen. Der XmlSerializer kümmert sich nicht um die Reihenfolge.

var xml = new XmlSerializer(typeof(ValidationResult)); 
var res = (ValidationResult)xml.Deserialize(reader); 
+1

Ich werde wahrscheinlich diesen Ansatz verwenden, jedoch habe ich den anderen als Antwort markiert, weil er die implizite Frage beantwortet ("Warum funktioniert das nicht?"). –

+0

Ich würde das gleiche tun. Meine Antwort, so nützlich sie auch sein mag, ist ein Workaround. –