views:

178

answers:

1

Hello, I am doing a finger exercise and trying to write a application that lets my computer and windows mobile phone communicate over bluetooth trough serial port.

Now I have ran into a snag with the serialization of objects. Binary seralization is not supported by .Net Compact Framework so I am opting for XmlSerialization. I have written a library with two classes. A ObjectCarrier that should be able to contain other classes so I can have a generic way of sending and receiving. And have a costume class MusicAlbum.

The entire setup works perfectly on the pc side. The mobile site keeps giving me the following error: System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type TransferObject.MusicAlbum was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

The strange thing is that if I use the ObjectCarrier and put something like a string or datetime object in the Payload it works on the mobile.

What am I doing wrong with my MusicAlbum class?

---| MusicListing.cs |-------------

using System;
using System.Collections.Generic;
using System.Text;

namespace TransferObject
{
    public class MusicAlbum
    {
        public string AlbumName { get; set; }
        public string ArtistName { get; set; }
    }

}

---| TransferObject.cs |-----------

using System;
using System.Xml.Serialization;

namespace TransferObject
{
    [XmlInclude(typeof(MusicAlbum))]
    public class ObjectCarrier
    {
        public Object PayloadObject { get; set; }
    }

}


Thank you for you suggetion. This helped me along to reveice how I am doing it. By using the abstract class I don't need a carrier anymore.

The reason it wasn't working was my own fault it was a windows library instead of a mobile library. After changing that your code worked perfectly. On both sides as far as I have tested now. If anything changes about I will update this.

+1  A: 

As far as I understand it, XmlInclude is used for subclasses; i.e. if MusicAlbum inherited from ObjectCarrier, and you were serializing a MusicAlbum instance as an ObjectCarrier.

IMO, the best approach here would be to use messages per-type; however, if you want to go the [XmlInclude] route you could define a common base-class to all your supported payloads, and have, for example:

[XmlInclude(typeof(MusicAlbum))] // etc other types...
public abstract class PayloadBase {}

public class MusicAlbum : PayloadBase
{
    public string AlbumName { get; set; }
    public string ArtistName { get; set; }
}

public class ObjectCarrier
{
    public PayloadBase PayloadObject { get; set; }
}

And btw, there are some APIs that support binary on CF; protobuf-net being just one (I'm biased as the author - but hey, it is free...).

Marc Gravell
+1 for recommending protobuf over XML.
ctacke