Frage

Ich bin im Begriff, eine WCF-Anwendung zu schreiben, das von einer Silverlight-Anwendung verbraucht wird. Ich habe die meisten der Design-Arbeit getan, und ich bin jetzt die Umsetzung zu tun, was mich mit dieser Frage kommen gemacht hat.

Hier ist ein Beispiel für etwas, das in meiner Anwendung vorhanden ist:

[DataContract]
class Person
{
    [DataMember]
    private Towel mostRecentlyUsedTowel;

    [DataMember]
    private Gym gym; //the gym that this person attends

    ...
}

[DataContract]
class Gym
{
    [DataMember]
    private List<Towel> towels; //all the towels this gym owns

    ...
}

Hier ist, was ich hinaus will: In meiner Anwendung mostRecentlyUsedTowel wird auf etwas in der Handtücher Liste für die Person, die Fitness-Studio zeigen. Einige meiner Anfragen werden eine Person Objekt serialisiert werden.

Ist das DataContractSerializer intelligent genug, um seine aufgefordert, zu bemerken, zweimal genau die gleiche Instanz eines Objekts serialisiert werden? Wenn ja, wie es damit umgehen?

Wenn es nur zweimal die gleiche Instanz über die Serialisierung gehen, wie soll ich damit umgehen, so bin ich nicht unnötigen Daten über die Verbindung zu senden?

War es hilfreich?

Lösung

Mit dem folgenden Code:

[TestMethod]
public void CanSerializePerson()
{
    var towel1 = new Towel() { Id = 1 };
    var towel2 = new Towel() { Id = 2 };
    var towel3 = new Towel() { Id = 3 };
    var gym = new Gym();
    gym.towels.Add(towel1);
    gym.towels.Add(towel2);
    gym.towels.Add(towel3);

    var person = new Person()
    {
      recentlyUsedTowel = towel1,
      gym = gym
    };

    var sb = new StringBuilder();
    using (var writer = XmlWriter.Create(sb))
    {
        var ser = new DataContractSerializer(typeof (Person));
        ser.WriteObject(writer, person);
    }

    throw new Exception(sb.ToString());
}

public class Person
{
    public Towel recentlyUsedTowel { get; set; }
    public Gym gym { get; set; }
}

public class Gym
{
    public Gym()
    {
        towels = new List<Towel>();
    }

    public List<Towel> towels { get; set; }
}


public class Towel
{
    public int Id { get; set; }
}

evaluieren zu:

<?xml version="1.0" encoding="utf-16"?>
<Person xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org">
  <gym>
    <towels>
      <Towel><Id>1</Id></Towel>
      <Towel><Id>2</Id></Towel>
      <Towel><Id>3</Id></Towel>
    </towels>
  </gym>
  <recentlyUsedTowel><Id>1</Id></recentlyUsedTowel>
</Person>

Wenn Sie die IsReference Eigenschaft auf das Datacontract Attribut der Towel Klasse wie folgt hinzugefügt:

[DataContract(IsReference=true)]
public class Towel
{
    // you have to specify a [DataMember] in this because you are 
    // explicitly adding DataContract
    [DataMember]
    public int Id { get; set; }
}

Sie würde eine Ausgabe wie diese:

<?xml version="1.0" encoding="utf-16"?>
<Person xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org">
  <gym>
    <towels>
      <Towel z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
        <Id>1</Id>
      </Towel>
      <Towel z:Id="i2" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
        <Id>2</Id>
      </Towel>
      <Towel z:Id="i3" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
        <Id>3</Id>
      </Towel>
    </towels>
  </gym>
  <recentlyUsedTowel z:Ref="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" />
</Person>

hoffe, das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top