Подтвердить что ты не робот

WCF: атрибут DataMember для свойства против члена

В wcf, в чем разница между применением атрибута DataMember для свойства

private int m_SomeValue;

[DataMember]  
public int SomeValue {
  get {...}
  set {...}
}

вместо переменной-члена

[DataMember]  
private int m_SomeValue;

public int SomeValue {
  get {...}
  set {...}
}

?

4b9b3361

Ответ 1

В общем, вам следует использовать атрибут DataMember для свойства, а не в частном поле. Единственная причина применить атрибут к полю вместо этого - если свойство было только для чтения (т.е. Оно не имеет сеттера).

Ответ 2

Пока вы используете маркер Name, контракт идентичен независимо от того, используется ли поле или свойство.

[DataMember(Name="SomeValue")]
private int m_SomeValue;

Однако могут возникнуть некоторые проблемы с правами доступа к частным членам, в частности, в silverlight и CF - в этом случае я бы рекомендовал использовать публичное свойство в качестве элемента данных. На самом деле, я бы всегда использовал свойство, если у меня не было очень веской причины...

Ответ 3

Есть веские причины, по которым вы можете пометить поля, а не свойства как DataMember.

Пожалуйста, проверьте это для более подробной информации: http://blog.walteralmeida.com/2010/05/wcf-and-datacontract-serialization-internals-and-tips-.html

Кстати: ContractSerializers сериализует любое частное поле с атрибутом DataMemberAttribute на нем только при запуске в полной среде доверия. Не работает в частичном доверии (проверьте блог, указанный выше для решения)

Ответ 4

Это деление зависит от использования вами службы WCF:

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

Случай 1.

Сериализация - это процесс сохранения состояния объекта. Состояние объекта в С# представлено полями данных.

Свойства в С# по существу - методы, которые управляют состоянием объекта. Использование их может привести к разным состояниям объектов десериализации, поскольку порядок, в котором установлены свойства, может повлиять на конечное состояние данных. Другие факторы могут привести к неправильной десериализации состояния, если, например, метод (свойство set) зависит от какого-то изменяющегося контекста, например текущего DateTime.

Вы можете сказать, что насчет инкапсуляции? Я не хочу, чтобы мой объект находился в недопустимом состоянии, и я должен выполнить проверки проверки, проверки целостности графа объектов и т.д. Да, вы должны, поэтому мы помещаем атрибуты DataMember в реквизиты? Нет.

Проблема в том, что многие люди смешивают две разные вещи: DTO (объект передачи данных, контракт WCF) с доменным сущностью. Вам нужно убедиться, что данные, которые вы получаете, - это те же самые данные, которые были отправлены, а затем убедитесь, что вы можете создать действительный домен из этих данных. Лучший способ достичь этого - использовать отдельные классы для DTO и построить из них объект Entity.

Но большинство программистов ленивы, и им нравится просто украшать Domain Entity атрибутами DataMemeber. В этом случае решение Field или Prop зависит от того, где ваша логика проверки, если ваша логика проверки похоронена в методах Set, вам придется использовать реквизиты, если она extenral, вы должны использовать поля и проверять ваш доменный объект после desirialization.

P.S. Я думаю, что одни и те же правила применимы к любому процессу сериализации, например к базе данных.

Кроме того, я хотел бы упомянуть, что Silverlight не может сериализовать \deserialize частные поля, потому что вы не можете обращаться к ним извне с помощью отражения, и вам придется сделать их частными и использовать InternalsVisibleToAttribute.

Случай 2.

Это сложно. Основное внимание здесь уделяется интероперабельности. В 99,9% у вас будут отдельные классы DTO в этом случае и, скорее всего, много разных версий для поддержки старых клиентов. Неважно, где вы ввели атрибуты DataMembers, потому что вы используете DTO. Я не буду разбираться в этом сценарии, потому что разработчики, которые работают в такой крупномасштабной системе, обычно достаточно опытны, и они не удосуживаются читать SO.

Ответ 5

В теории, и до тех пор, пока вы держите m_SomeValue всегда равным SomeValue (как простой геттер/сеттер), ничего. Кроме имени переменной, отображаемой WCF. (Очевидно, что если вы помечаете переменную m_, то ваш прокси-класс также будет иметь то же имя m_. Прокси-класс будет генерировать общедоступное свойство, независимо от того, используете ли вы публичное/защищенное/внутреннее/частное поле или свойство.

Однако, если у вас есть какая-либо специальная логика в ваших аксессуарах, которая может изменить возвращаемое значение (например, ToUpper() строка, например), вы должны вернуть другое значение.

Ответ 6

Лично я бы просто использовал свойство и полностью удалил переменную-член все вместе. то есть.

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

Свойство будет необъяснимо создавать переменную-член за кулисами.

Ответ 7

Если добавить [DataMember] в private int m_SomeValue, этот член не может быть сериализацией, поэтому его необходимо добавить в public int SomeValue.

[DataMember]
private int m_SomeValue;

public int SomeValue { получить {...} задавать {...} }

код выше не может быть получен в клиенте, если вы используете его через WCF.