Jacob
Jacob

Reputation: 797

XmlSerializer is not serializing to a valid xml

Please Consider the following code:

public class Obj : IObj
{
    public string Prop1{get;set;}
    public string Prop2{get;set;}
    public string Prop3{get;set;}
}

public static void Persist(IObj obj, string fileFullName)
{
    try
    {
        Directory.CreateDirectory(Path.GetDirectoryName(fileFullName));

        var xmlSerializer = new XmlSerializer(obj.GetType());

        using (var fileStream = File.Open(fileFullName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
        {
            xmlSerializer.Serialize(fileStream, obj);
            fileStream.Close();
        }
    }
    catch (Exception e)
    {
       //log
    }
}

When calling 'Persist' on 'Obj' for the first time, I get a valid xml file on disk, which looks something like this:

<?xml version="1.0"?>
<Obj xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Prop1>value1</Prop1>
    <Prop2>value2</Prop2>
    <Prop2>value3</Prop3>
</Obj>

But when 'Persist' is called for the second time on 'Obj' (after changing 'value1' to 'value', for example), an extra '>' sign is added at the end of the file, making it non-valid.

<?xml version="1.0"?>
<Obj xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Prop1>value</Prop1>
    <Prop2>value2</Prop2>
    <Prop2>value3</Prop3>
</Obj>>

I tried to debug it but didn't find any abnormalities, so I'm guessing it has to do with the way that I'm opening the file. Any help explaining it would be appreciated.

Upvotes: 3

Views: 869

Answers (2)

Rowland Shaw
Rowland Shaw

Reputation: 38129

I suspect you'll only see this when the subsequent XML is smaller than the previous - You need to set the length of the fileStream with something like:

xmlSerializer.Serialize(fileStream, obj);
if (fileStream.CanSeek)
{
     fileStream.SetLength(fileStream.Position);
}

Alternately, specify FileMode.Create when creating the stream

Upvotes: 2

David M
David M

Reputation: 72930

If the file exists, you are opening it and overwriting as many bytes as needed. If that's fewer than the current file length, you'll have left over characters at the end. Try using FileMode.Create instead.

Upvotes: 8

Related Questions