4
votes

I'm attempting to write objects to azure blobs for persistent storage and for some reason 1 property is never serialized and i'm unsure why.

This is the object

[Serializable]
public class BlobMetaData
{
    public DateTimeOffset? ModifiedDate { get; set; }
    public string ContentType { get; set; }
    public string Name { get; set; }
    // size of the file in bytes
    public long Length { get; set; }
}

this is the function that saves the data to Azure storage.

public void Save(string filename,BlobProperties blobProperties)
{
    //full path to the blob
    string saveFile = _clientDirectory + filename;
    CloudBlockBlob blockBlob = _blobContainer.GetBlockBlobReference(saveFile);
    //blobMetaData properly gets all the right values.
    BlobMetaData blobMetaData = ConvertBlobProperties(blobProperties,filename);
    // I convert it to a stream
    MemoryStream stream = SerializeToStream(blobMetaData);
    blockBlob.UploadFromStream(stream);
}

Here is how I serialize the data.

    private MemoryStream SerializeToStream(BlobMetaData blobMetaData)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(BlobMetaData));
        MemoryStream stream = new MemoryStream();
        serializer.Serialize(XmlWriter.Create(stream), blobMetaData);
        stream.Seek(0, SeekOrigin.Begin);
        return stream;
    }

for some reason.. all values are properly stored in Azure XML except the ModifiedDate.. it is always blank even though before I call SerializeToStream() I check blobMetaData and it does have the value.. so its getting lost during the serialization process.

Here is what the XML looks like

<?xml version="1.0" encoding="utf-8"?><BlobMetaData   
xmlns:xsd="http://www.w3.org/2001/XMLSchema"   
xmlns:xsi="http://www.w3.org/2001/XMLSchema- 
instance"><ModifiedDate /><ContentType>application/octet-stream</ContentType><Name>u_ex14060716.log</Name><Length>652</Length></BlobMetaData>

as you can see modifiedDate is empty. Anyone have any idea why?

2
The only thing I notice that could cause issues (potentially) is that modifiedDate is that modifiedDate is nullable. Is there any chance that it hasn't been set?Dan Drews
@DanDrews Even if it is not nullable i am getting the same behaviorGary.S

2 Answers

6
votes

So the answer seems to be that DateTimeOffset was not designed to be serialized with the XmlSerializer (http://connect.microsoft.com/VisualStudio/feedback/details/288349/datetimeoffset-is-not-serialized-by-a-xmlserializer).

The workaround appears to be to create properties that can be serialized (either string or DateTime and int for offset) or to use the datacontract serializer per the connect bug.

This question has more possible solutions in it.

How can I XML Serialize a DateTimeOffset Property?

3
votes

From Microsoft Support:

The DateTimeOffset type was not designed to be used with the XmlSerializer. The XmlSerializer requires that a type be designed in a specific way in order to serialize completely (default public constructor, public read\write members, etc). Most types in the .NET Framework were not designed with the XmlSerializer in mind.

Instead, you should use the DataContractSerializer to serialize this type into XML. If you must use the XmlSerializer, consider creating your own type in combination with DateTime to correctly serialize the information you are interested in.

The same thread did also identify it as a bug to be fixed, so you could try to find out if it had been fixed in a later version of the .NET framework or not if you are not on the latest.

If you must still use XmlSerializer, then you can find potential workaround(s) in another thread at stackoverflow.

If I were to do it, I would use DataContractSerializer instead, especially given that the type you are using is not that large.