how to mark an interface as DataContract in WCF
Asked Answered
E

2

15


i have two data classes which hold only data members(no functions). One is CallTask the other is SmsTask. These two classes have some common properties like ID, Tel. I put these common properties in a seperate interface class and i use this interface class in my project whenever appropriate.
Now i added a WCFService to my project to share data between clients and server. Consider the following class design:

public interface IGsmTask : IComparable
{
    string TaskID { get; set; }
    string SessionID { get; set; }
    string Tel { get; set; }
}

class CallTask : IGsmTask
{
    #region IGsmTask Members

    public string TaskID { get; set; }

    public string SessionID { get; set; }

    public string Tel { get; set; }

    #endregion        
}

class SmsTask : IGsmTask
{
    #region IGsmTask Members

    public string TaskID { get; set; }

    public string SessionID { get; set; }

    public string Tel { get; set; }

    #endregion

    public string SmsText { get; set; }
}

in this design, i want to host CallTask, SmsTask, and IGsmTask to the clients to use these in service methots like the following;

    [OperationContract]
    public void AddTask(IGsmTask task)
    {

    }

i tried to mark [DataContract] on IGsmTask but it gives me complition error. Isnt there any methot that i can use interfaces as DataContracts? Or how should i use KnownAttributes types in this synerio?
Thanks.

Entreat answered 2/4, 2012 at 8:0 Comment(3)
Thanks Reniuz it seems that i can not use interfaces for this purpose.Entreat
WCF is a message-based system - the client sends an XML-serialized message to the server. As such, those messages must be concrete types that can be serialized into XML and represented with an XML schema. Interfaces cannot be serialized into XML ....Harrell
Well first thing that I would do is create class to store common properties, not interface. In this way you save at least 3 lines in each derived class.Slaughterhouse
M
13

As far as I know using interfaces as datacontracts is not possible. You may use a base class and add knowntype attributes on the otherhand.

Montherlant answered 2/4, 2012 at 8:3 Comment(2)
i thought there would be a methot using interfaces as datacontracts. if it is not possible i will have to change my interface to a base class. Thanks.Entreat
Since serialization is based on object instances, I think there is no direct way to do it.Montherlant
G
10

Fer: Everything is Possible with the right design.

If the issue is:

a class is a data contract

&&

1 or more of its properties must be an interface...

public interface ICustomInterface
{
    int Property1 {get;set}
}

[DataContract]
public class MyClass
{
     [DataMember(Name="_myInterface")]
     public ICustomInterface MyInterface {get;set;}
}

The issue is that when the de-serialization occurs -- There is no way to turn the data into a class that implements ICustomInterface.

The Solution is to create a concrete class that does Implement the interface, and cast the getter/setter of the public property (that is of type interface) into a private property of the concrete class.

public class CustomInterfaceImplementor: ICustomInterface
{
     public int Property1 {get;set;}
}

[DataContract]
public class MyClass
{
     [DataMember(Name="_myInterface")]
     private CustomInterfaceImplementor _MyInterface;
     public ICustomInterface MyInterface
     {
          get {return (_MyInterface as ICustomInterface);}
          set {_MyInterface = (value as CustomInterfaceImplementor);}
     }
}
Genteel answered 5/11, 2013 at 18:9 Comment(2)
creating a new class means that everything has to again be initialized. which is a hassle if you just want to leave out a few properties. i consider this yet another language limitationPneumonoultramicroscopicsilicovolcanoconiosis
It seems to work just using: get { return _MyInterface; } set { _MyInterface = value; } So you can leave the as out.Highmuckamuck

© 2022 - 2024 — McMap. All rights reserved.