Search code examples
c#monodatacontractserializer

Trouble with deserialization in mono


Anyone have any idea why the following XML generated by a data contract serializer in C# works just fine in Windows but not under Linux on Mono?

The XML:

<Message i:type="UserMessage" xmlns="http://schemas.datacontract.org/2004/07/NetTunnel"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><type>UserMessage</type>
<nick>Unnamed</nick><services><Service><enabled>true</enabled><port_ranges i:nil="true"/>
<service_name>vent</service_name></Service></services><state>Created</state>
<userid>1</userid></Message>

The error:

Unhandled Exception: System.Runtime.Serialization.SerializationException: Deserializing 
type 'System.Object'. Expecting state 'EndElement'. Encountered state 'Element' with 
name 'enabled' with namespace 'http://schemas.datacontract.org/2004/07/NetTunnel'.

It also gives me an error if there are no services listed (xml tag <services/>). The services variable is of type List<Service>. Is this just a type Mono can't handle? Would another type be more appropriate? Or is it something else entirely?


Solution

  • From the comments, you don't need WCF and just want to share data. In which case, I would look at protobuf-net. I'm quite biased (since I'm the author), but it is free (with source), so I'm not recommending it from self gain. Simply; it is a fast, portable serialization API modelled after google's "protocol buffers" data format. Very fast to process (typically much faster than xml, for example) and pretty small on the wire.

    If you already using data-contracts, you might be able to tweak them simply by adding unique Order values (it uses this as a numeric identifier):

    [DataContract]
    public class Foo {
        [DataMember(Order = 1)]
        public int Id {get;set;}
    
        [DataMember(Order = 2)]
        public string Name {get;set;}
    }
    

    (or you can use the specific protobuf-net attributes)

    The full source is available, and it works on Mono, regular .NET, CF, etc.