Achim Stuy
Achim Stuy

Reputation: 51

`DataContractSerializer` deserialize child class into base class

I have following on my server:

[DataContract]
public class Base { }

[OperationContract]
void DoSth(Base base) { }

and on my client:

class Child : Base { }

When calling the server with DoSth(child) I get a serialization exception, because Child is not known to the WCF DataContractSerializer:

System.ServiceModel.CommunicationException: There was an error while trying to serialize parameter http://tempuri.org/:base. The InnerException message was 'Type 'Child' with data contract name 'Child:http://schemas.datacontract.org/2004/07/Client' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'.  Please see InnerException for more details.
 ---> System.Runtime.Serialization.SerializationException: Type 'Child' with data contract name 'Child:http://schemas.datacontract.org/2004/07/Client' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

And I don't want to make it known, because the server uses only Base's properties. How can I send my data as Base object

I know, I could create a new Base object and copy all properties, but this is not really elegant.


Following @QiYou's answer:

[DataContract(Name = "Base", Namespace = "http://schemas.datacontract.org/2004/07/Server")]
class Child : Base { }

also doesn't work, because the underlying types of the data contract differ.

Upvotes: 0

Views: 95

Answers (1)

QI You
QI You

Reputation: 518

I tested it with WCF's template example.

I inherit in the client's Reference.cs:

Here's an example:

Server-side:

    [DataContract]
    public class CompositeType
    {
   
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]    
            public bool BoolValue
            {
                get { return boolValue; }
                set { boolValue = value; }
            }

        [DataMember]
        public string StringValue
{
    get { return stringValue; }
    set { stringValue = value; }
}
        }

client-side:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name = "CompositeType", Namespace = "http://schemas.datacontract.org/2004/07/WcfService4")]
    [System.SerializableAttribute()]
    public class Child : CompositeType
    {
        [DataMember]
        public bool BoolValue { get; set; }
        [DataMember]
        public string StringValue { get; set; }
    
    }

At the moment the test program can run, you can try my method.

Upvotes: 0

Related Questions