DataContract runtime error - Type 'myType' cannot be serialized. What i'm doing wrong?

13,973

Alright, got it!

I posted the solution in my blog: http://livshitz.wordpress.com/2012/11/06/wcf-serialization-datacontract-runtime-error-type-mytype-cannot-be-serialized/

After fighting and cutting all possible parts of that “shared” class, I got to the problematic area.

The problem was that I used interface as a member (or list of..), which associated with Driven classes.

And that’s it! The serializer having problem figuring out how to serialize that member, so here is the solution:

When using interface as a member (or list of interface) in a class that is about to be serialized and shared via WCF, the Shared class must specify the possible types of the interface by adding to it:

[System.Runtime.Serialization.KnownType(typeof(JobA))]
[System.Runtime.Serialization.KnownType(typeof(JobB))]

And each of those types must be marked with:

[System.Runtime.Serialization.DataContract]

Note: Since JobBase is abstract, no reason to mark it with KnownType...

That’s it.

Share:
13,973
Elya Livshitz
Author by

Elya Livshitz

Linkedin profile: http://il.linkedin.com/in/elyalivshitz | Blog: http://livshitz.wordpress.com

Updated on June 14, 2022

Comments

  • Elya Livshitz
    Elya Livshitz almost 2 years

    Trying to pass "complex" class type that contains primitive types with interfaces and lists of interfaces/classes.

    I guess the problematic member is:

    public List<IMyInterface> IntrfList
    

    Runtime Error:

    An error occurred while receiving the HTTP response to http:/localhost/xxxxxx/xxxxxService.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.

    The descriptive error from MS Service Trace Viewer (SvcTraceViewer):

    Type 'myType' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.

    I did as the explanation suggests but didn't help.

    The "shared" class:

    [System.Runtime.Serialization.DataContract]
        public class ServerState
        {
            private Queue<IJob> _mWaitingQueue;
            public Queue<IJob> mWaitingQueue
            {
                get
                {
                    lock (_LockObjWaiting)
                    {
                        return _mWaitingQueue;
                    }
                }
                private set
                {
                    _mWaitingQueue = value;
                }
            }
            private object _LockObjWaiting = new object();
    
            private List<IJob> _mInPrograssList = new List<IJob>();
    
            [DataMember]
            public List<IJob> mInPrograssList
            {
                get
                {
                        return _mInPrograssList;
                }
                private set
                {
                    _mInPrograssList = value;
                }
            }
    }
    

    IJob is an interface. The structure of IJob is like this:

    IJob (Interface)
      - JobBase (Abstract class)
        - JobA (Driven from JobBase)
        - JobB (Driven from JobBase)