как пометить интерфейс как DataContract в WCF - PullRequest
14 голосов
/ 02 апреля 2012


у меня есть два класса данных, которые содержат только члены данных (без функций). Один - CallTask ​​, другой - SmsTask . Эти два класса имеют некоторые общие свойства, такие как ID , Tel . Я поместил эти общие свойства в отдельный класс интерфейса и использую этот класс интерфейса в своем проекте, когда это уместно.
Теперь я добавил WCFService в свой проект для обмена данными между клиентами и сервером. Рассмотрим следующий дизайн класса:

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; }
}

в этом дизайне я хочу разместить CallTask, SmsTask и IGsmTask для клиентов, чтобы использовать их в методах обслуживания, как показано ниже:

    [OperationContract]
    public void AddTask(IGsmTask task)
    {

    }

Я пытался пометить [DataContract] на IGsmTask , но это дает мне ошибку завершения. Есть ли какой-либо метод, который я могу использовать интерфейсы как DataContracts? Или как мне использовать типы KnownAttributes в этом synerio?
Спасибо.

Ответы [ 2 ]

13 голосов
/ 02 апреля 2012

Насколько я знаю, использование интерфейсов в качестве контрактов невозможно. Вы можете использовать базовый класс и добавить атрибуты knowntype с другой стороны.

10 голосов
/ 05 ноября 2013

Fer: все возможно с правильным дизайном.

Если проблема:

, класс является контрактом данных

&&

1 или более его свойств должны быть интерфейсом ...

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

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

Проблема в том, что когда происходит десериализация - нет способа превратить данные в класс, реализующий ICustomInterface.

Решение заключается в создании конкретного класса, которыйРеализует интерфейс и преобразует метод получения / установки открытого свойства (то есть типа интерфейса) в личное свойство конкретного класса.

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);}
     }
}
...