Question

My NetDataContractSerializer seems to be confused: The end of the XML appears twice:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns:i="http://www.w3.org/2001/XMLSchema-instance" z:Id="1" 

[...]
        <d2p1:anyType i:nil="true" />
      </d2p1:_items>
      <d2p1:_size>2</d2p1:_size>
      <d2p1:_version>2</d2p1:_version>
    </d2p1:items>
  </ProjectParts>
  <ProjectPath z:Id="31">D:\t10\</ProjectPath>
</Project>ze>
              <d2p1:_version>3</d2p1:_version>
            </d2p1:items>
            <d2p1:_monitor xmlns:d7p1="http://schemas.datacontract.org/2004/07/System.Collections.ObjectModel" z:Id="33">
              <d7p1:_busyCount>0</d7p1:_busyCount>
            </d2p1:_monitor>
          </Elements>
          <Project z:Ref="1" i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/Modules.WorkspaceManager.Types" />
        </d2p1:anyType>
        <d2p1:anyType i:nil="true" />
        <d2p1:anyType i:nil="true" />
      </d2p1:_items>
      <d2p1:_size>2</d2p1:_size>
      <d2p1:_version>2</d2p1:_version>
    </d2p1:items>
  </ProjectParts>
  <ProjectPath z:Id="34">D:\t10\</ProjectPath>
</Project>

As you can see, there is some serious stammering going on. It happens occasionally and I can't reproduce the error. Any ideas? Could it be caused by the file being opened in VS while it's being written?

I serialize my object like this:

private void SerializeToFile(object objectToSerialize)
    {
        Stream stream = null;

        try
        {
            stream = File.Open(_fileName, FileMode.OpenOrCreate, FileAccess.Write);
            using (var writer = XmlWriter.Create(stream, new XmlWriterSettings { Indent = true }))
            {
                NetDataContractSerializer serializer = new NetDataContractSerializer();
                serializer.WriteObject(writer, objectToSerialize);
            }
        }

        finally
        {
            if (stream != null) stream.Close();
        }
    }

And the class serialized looks like this:

[DataContract(IsReference = true)]
public class Project : IProject
{
    [DataMember] public string ProjectPath { get; set; }
    [DataMember] public string ProjectName { get; set; }
    [DataMember] public Collection<IProjectPart> ProjectParts { get; set; }

    public T GetPart<T>() where T : IProjectPart
    {
        return ProjectParts.OfType<T>().First();
    }

    public void RegisterPart<T>(T part) where T : IProjectPart
    {
        if (ProjectParts.Any(p => p.GetType().IsInstanceOfType(part))) throw new InvalidOperationException("Part already registered.");
        ProjectParts.Add(part);
        part.Project = this;
    }

    public void Load()
    {
        foreach (var projectPart in ProjectParts)
        {
            projectPart.Load();
        }
    }

    public void Unload()
    {
        foreach (var projectPart in ProjectParts)
        {
            projectPart.Unload();
        }
    }

    public void Save()
    {
        foreach (var projectPart in ProjectParts)
        {
            projectPart.Save();
        }
    }

    public Project()
    {
        ProjectParts = new Collection<IProjectPart>();
    }
}

Thank you!

Was it helpful?

Solution

The issue is simple - when you serialize over and over your object, you do it with different size of IProjectPart collection. The File.Open method does not clear the file from previous content so assume following steps :

i) serialize object with two IProjectPart instaces - let's say it will take 10 lines of xml file

ii) serialize object again with one IProjectPart instance in the collection - this time it will take 8 lines of xml file

iii) lines 9 and 10 will be filled with old xml data since they are not cleared between serialization attempts - so there is some duplicated-trash-looking xml data.

Try it for yourself , you will see exactly how those multiple tags are generated.

NOTE : The 8 and 10 lines are approximate values for my implementation

NOTE 2 : I suggest using using statement for the stream inside serialization method(as for all IDisposable objects) :

private void SerializeToFile(object objectToSerialize)
{
    using(var stream = File.Open(_fileName, FileMode.OpenOrCreate, FileAccess.Write))
    {
        using (var writer = XmlWriter.Create(stream, new XmlWriterSettings { Indent = true }))
        {
            NetDataContractSerializer serializer = new NetDataContractSerializer();
            serializer.WriteObject(writer, objectToSerialize);
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top