WCF - создание объекта в конструкторе DataContract - PullRequest
7 голосов
/ 17 сентября 2011

У меня есть два класса, как показано ниже:

[DataContract]
public class Address
{
   [DataMember]
   public string Line1
   [DataMember]   
   public string Line2
   [DataMember]
   public string City
   [DataMember]
   public string State
   [DataMember]
   public string Zip
}

[DataContract]
public class Customer
{
   public Customer()
   {
      CustomerAddress = new Address();
   }

   [DataMember]
   public string FirstName
   [DataMember]
   public string LastName
   [DataMember]
   public Address CustomerAddress
}

Что произойдет, если я сгенерирую прокси своего сервиса, который использует класс Customer?Если я правильно понимаю концепцию, то я думаю, что конструктор в классе Customer не будет вызываться на стороне клиента, и он может дать другое поведение.

Как избавиться от этого конструктора в классе Customer и до сих пориметь свойство CustomerAddress типа Address, чтобы оно действовало как тупой объект DTO?

Какое общее руководство или передовой опыт используют люди, чтобы избежать этой ситуации?

Ответы [ 3 ]

6 голосов
/ 17 сентября 2011

Если вы используете по умолчанию DataContractSerializer для сериализации ваших объектов, то да, ваш конструктор не сериализован, и любая логика, которая у вас может быть в нем, не будет вызываться вашим клиентом при десериализации объекта.

Относительно вашего вопроса об удалении логики конструктора и заполнении вложенного класса Address, о котором позаботится DataContractSerializer. Если у меня есть такой код:

Customer c = new Customer() { 
  FirstName = "David",
  LastName = "Hoerster",
  CustomerAddress = new Address() {
    Line1 = "1 Main Street",
    City = "Smallville",
    State = "AA",
    Zip = "12345"
  }
};

и затем вернуть его из метода службы, этот объект Customer будет сериализован должным образом вместе с информацией Address. Сгенерированный прокси на клиенте будет знать о Address и сможет десериализовать поток, поступающий от метода сервиса, чтобы правильно построить объект Customer. Ваш Customer будет фиктивным DTO - никакой логики, только свойства.

Ознакомьтесь с статьей MSN Аарона Сконнарда о сериализации WCF, где он рассказывает о DataContractSerializer.

1 голос
/ 17 сентября 2011

Если вы сгенерируете клиента (используя svcutil или «добавить ссылку на сервис»), то сгенерированный DataContract будет выглядеть так:

[DataContract]
public class Customer
{
   // empty default constructor
   public Customer()
   {
   }

   [DataMember]
   public string FirstName
   [DataMember]
   public string LastName
   [DataMember]
   public Address CustomerAddress
}

Детали вашей реализации не перенесены. Все, что генерируется, - это то, что входит в WSDL, который в данном случае является просто [DataMember] свойствами.

Я упоминаю об этом, потому что ваш оригинальный вопрос спрашивает: " Что произойдет, если я сгенерирую прокси ".


Если это объект, отправляемый с сервера на клиент, то вы всегда можете просто инициализировать CustomerAddress перед отправкой его клиенту. Фактически, если ваш исходный код находится на сервере, то этот конструктор будет запущен, и WCF будет сериализовать CustomerAddress и в основном никогда не отправит ноль (если вы не установите его обратно в нуль после конструктора).

Если вы хотите сделать так, чтобы клиент всегда отправлял вам CustomerAddress, то вы могли бы:

  • имеет сервер проверка на ноль, как if(x.CustomerAddress == null) x.CustomerAddress = new Address();
  • пометьте DataMember как необходимый, тогда сервер вернет ошибку, если клиент ничего не передал: [DataMember(IsRequired=true)] public Address CustomerAddress;

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

0 голосов
/ 17 сентября 2011

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

...