tags:

views:

530

answers:

1

I have classes in my service defined as

[DataContract]
[KnownType(typeof(MyConcrete1)) ]
[KnownType(typeof(MyConcrete2)) ]
public abstract class MyAbstract
{
    [DataMember]
    public int AbsInt { get; set; }
}
[DataContract]
public  class MyConcrete1 : MyAbstract
{
    [DataMember]
    public int Concrete1Int { get; set; }
}
[DataContract]
public class MyConcrete2 : MyAbstract
{
    [DataMember]
    public int Concrete2Int { get; set; }
}

and in my Service, I use it as

[ServiceContract]
public interface IService1
{
    [OperationContract]
    MyAbstract TestAbstract(MyAbstract value);
}

As you can see, the method TestAbstract takes and returns the abstract parameter MyAbstract, however in the client proxy generated by SvcUtil, the type "MyAbstract" is not abstract! It generated a concrete class.

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name = "MyAbstract", Namespace = "http://schemas.datacontract.org/2004/07/WcfService")]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(WcfService.MyConcrete1))]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(WcfService.MyConcrete2))]
public partial class MyAbstract : object, System.Runtime.Serialization.IExtensibleDataObject
{

    private System.Runtime.Serialization.ExtensionDataObject extensionDataField;

    private int AbsIntField;

    public System.Runtime.Serialization.ExtensionDataObject ExtensionData
    {
        get
        {
            return this.extensionDataField;
        }
        set
        {
            this.extensionDataField = value;
        }
    }

    [System.Runtime.Serialization.DataMemberAttribute()]
    public int AbsInt
    {
        get
        {
            return this.AbsIntField;
        }
        set
        {
            this.AbsIntField = value;
        }
    }
}

How can I force svcUtil to generate MyAbstract as an abstract class? I'm stuck, please help...

+1  A: 

You cannot - svcutil cannot know that MyAbstract class is abstract. The metadata that's being exchanged between server and client just doesn't support such a concept. The SOA world doesn't always support everything the OO world has in store.

The service metadata only knows about things like services, method calls, and data contracts - anything else is not part of the service metadata.

You will need to add some extra logic and tweaking to the client code, once it's been creating, if that's a real requirement on your side.

Marc

marc_s
I suppose its the DataContractSerializer that doesn't support this. XmlSerializer does though. For example if you point svcutil to a web service that uses abstract classes it can create the abstract classes on the client. Do it on a WCF service and it can't anymore.