Какой смысл DataContract в WCF? - PullRequest
       21

Какой смысл DataContract в WCF?

50 голосов
/ 19 ноября 2008

VS.net создает шаблон при создании проекта WCF.

Добавляет класс в файл iService1.cs:

// Use a data contract as illustrated in the sample below to
// add composite types to service operations.
[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; }
    }
}

Поскольку служба WCF может возвращать любой определенный пользователем класс, зачем использовать классы DataContract и CompositeType?

Я могу вернуть что-то вроде:

 [OperationContract]
MyUserCollection GetUsers();

Чего мне не хватает?

Ответы [ 6 ]

51 голосов
/ 19 ноября 2008

DataContract - это просто формальное определение типа, которое может быть понято по обе стороны границы сервиса.

Если вы возвращаете, как в вашем примере, объект «MyUserCollection», потребители вашего сервиса должны будут ссылаться на внутренности вашего сервиса / системы, что является нарушением принципа SOA явных границ. Используя DataContract, вы публикуете структуру типов возвращаемых данных в слабосвязанной форме.

26 голосов
/ 20 ноября 2008

Еще одна интересная вещь: если вы украшаете свой код с помощью DataContract, у вас есть большой контроль над тем, что клиент может увидеть и должен отправить обратно в ваш сервис. Например:

[DataContract]
public class SampleClass
{
    [DataMember(IsRequired=true)]
    public int MyRequiredProperty { get; set; }

    [DataMember]
    public int MyOptionalProperty { get; set; }

    public int MyInternalProperty { get; set; }
}

В приведенном выше примере вы определили, что при получении данных вы ДОЛЖНЫ иметь MyRequiredProperty и можете иметь или не иметь MyOptionalProperty. Кроме того, клиент никогда не увидит MyInternalProperty (это может быть, например, какое-то свойство, которое помогает вашей внутренней логике, но вы не хотите, чтобы оно отображалось на уровне клиента).

11 голосов
/ 05 апреля 2011

Существует еще одно важное использование, вы можете изменить имя класса и свойства. Это удобная функция при сериализации и десериализации.

[DataContract(Name="EmployeeName")]
public class Person
{
   [DataMember(Name="FullName")]
   public string Name { get; set; }

   [DataMember(Name="HomeAddress")]
   public string Address { get; set; }
}
2 голосов
/ 07 августа 2010

Для ответа на "marc_s":

"Если у вас есть .NET на обоих концах провод, это просто отлично. Что делать, если вы есть клиент Java, звонящий вашему оказание услуг? Если вы положите свои данные внутри DataContracts, эта информация получает хранятся в метаданных WSDL / XSD и могут быть использованы клиентами, кроме .NET тоже. "

Я думаю, что это неверно. Давайте попробуем сделать это:

  1. Использовать пример WCF по умолчанию проект с классом с Атрибуты DataContract для классов и DataMember на членов, и метод, который возвращает этот тип.
  2. Постройте его и отобразите wsdl. Xsd содержит определение CompositeType. OK.
  3. Теперь давайте удалим все атрибуты DataContract и DataMember
  4. Постройте его и отобразите wsdl. XSD по-прежнему содержит определение ComposityType! (это более очевидно с программным обеспечением SCM, которое не показывает разницы в файлах между шагами 2 и 4)

Таким образом, клиент Java должен управлять этим без DataContract и DataMember! Я не прав или что?

2 голосов
/ 20 июля 2010

Я не согласен с автором, который сказал: «DataContract - это просто формальное определение типа, которое может быть понято по обе стороны границы обслуживания».

Ключевое слово здесь "тип". В .NET тип - это объект, который может иметь поля, свойства и методы. Однако, когда вы украшаете класс с помощью DataContract в вашей службе WCF, результатом является не то, что класс волшебным образом трансплантируется в вызывающий код; отнюдь не! В коде вызова у вас будет класс «прокси». Прокси-класс получает XML, который представляет содержимое контракта с данными. Вызывающий код может получать эти значения XML через прокси-класс, но он не предоставляет вызывающему коду доступ к внутренностям класса, украшенным datacontract.

0 голосов
/ 08 февраля 2013

Возможно, не часто используется, мы могли бы использовать [DataContract] для прохождения через частные переменные. DataContractSerializer сериализует / десериализует только общедоступные типы, если атрибут [DataContract] не используется.

[DataContract]
public class SampleClass
{    
    [DataMember]
    private int MyPrivateProperty { get; set; }
}

(Примечание. Если вы генерируете прокси-сервер, частные участники будут представлены как открытые)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...