简体   繁体   中英

DataContractSerializer can't find reference?

at first: sorry if this is a long and code heavy question. i am trying to serialize and deserialize a class called level that looks like this:

[DataContract]
public class Level
{
    [DataMember]
    public List<Face> faces;

    public Level()
    {
        Face a = new Face();
        Face b = new Face();
        Face c = new Face();
        Face d = new Face();

        a.edges.Add(new Edge(b, c));
        b.edges.Add(new Edge(a, c));
        c.edges.Add(new Edge(a, d));
        d.edges.Add(new Edge(a, b));

        this.faces = new List<Face>() { a, b, c, d };
    }
}

[DataContract(IsReference = true)]
public class Face
{
    [DataMember]
    public List<Edge> edges;
    public Face()
    {
        this.edges = new List<Edge>();
    }
}

[DataContract(IsReference = true)]
public class Edge
{
    [DataMember]
    public Face a;
    [DataMember]
    public Face b;

    public Edge(Face a, Face b)
    {
        this.a = a;
        this.b = b;
    }
}

since there are circular references i need to enable the reference function of the datacontract serializer.However when i run this i get the error

SerializationException: Deserialized object with reference Id 'i1' was not found

the serialize and deserialize functions look like this:

// object to be serialized
public Level level;

public void Serialize()
{
    DataContractSerializer serializer = new DataContractSerializer(typeof(Level));
    FileStream stream = new FileStream(Path.Combine(Application.dataPath, "test.xml"), FileMode.Create);
    Debug.Log("serial");
    serializer.WriteObject(stream, level);
    stream.Close();
}

// function to serialize an object to a json text file
public void Deserialize()
{
    FileStream stream = new FileStream(Path.Combine(Application.dataPath, "test.xml"), FileMode.Open);
    DataContractSerializer serializer = new DataContractSerializer(typeof(Level));

    Level loaded = (Level)serializer.ReadObject(stream);

    stream.Close();
}

void Start()
{
    level = new Level();
    Serialize();

    Deserialize();
}

here is also a serialized xml example:

<Level xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/">
    <faces>
        <Face z:Id="i1" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
            <edges>
                <Edge z:Id="i2">
                    <a z:Id="i3">
                        <edges>
                            <Edge z:Id="i4">
                                <a z:Ref="i1" />
                                <b z:Id="i5">
                                    <edges>
                                        <Edge z:Id="i6">
                                            <a z:Ref="i1" />
                                            <b z:Id="i7">
                                                <edges>
                                                    <Edge z:Id="i8">
                                                        <a z:Ref="i1" />
                                                        <b z:Ref="i3" />
                                                    </Edge>
                                                </edges>
                                            </b>
                                        </Edge>
                                    </edges>
                                </b>
                            </Edge>
                        </edges>
                    </a>
                    <b z:Ref="i5" />
                </Edge>
            </edges>
        </Face>
        <Face z:Ref="i3" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" />
        <Face z:Ref="i5" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" />
        <Face z:Ref="i7" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" />
    </faces>
</Level>

i searched for an answer for a few days now and still didn't get any close. Can you give me a hint on how to solve this please?

I think your problem may be that you are trying to deserialize something that you previously serialized before you added the IsReference=true parameter to the attribute.

If you delete your test file and create a new one with your updated code, the deserialization process should work without issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM