WCF: DataMember attribute for property versus member

In wcf, what is the difference between applying the DataMember to a property

 private int m_SomeValue; [DataMember] public int SomeValue { get {...} set {...} } 

instead of a member variable

 [DataMember] private int m_SomeValue; public int SomeValue { get {...} set {...} } 

?

+53
serialization wcf
Feb 17 '09 at 13:26
source share
7 answers

In general, you should use the DataMember attribute for a property, not a private field. The only reason to apply the attribute to the field instead is if the property was read-only (i.e., it has no setter).

+41
Feb 17 '09 at 14:29
source share

As long as you use the Name token, the contract is identical regardless of whether the field or property is being used.

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

However, there may be some problems with access rights to private members, in particular in silverlight and CF - in this case, I would recommend using a public property as a data element. In fact, I would always use a property if I didn’t have a very good reason ...

+24
Feb 17 '09 at 13:53
source share

There are good reasons why you can mark fields, rather than properties, as a DataMember.

Please check this for more details: http://blog.walteralmeida.com/2010/05/wcf-and-datacontract-serialization-internals-and-tips-.html

By the way: ContractSerializers serializes any private field with the DataMemberAttribute attribute on it only when launched in a full trust environment . Does not work in partial trust (check out the blog above for a solution)

+6
May 28 '10 at 13:40
source share

This division depends on your use of the WCF service:

  • The internal service consumed by your own .NET systems that use the same domain model.
  • An external service consumed by different platforms that do not use the same domain model.

Case 1

Serialization is the process of maintaining the state of an object. The state of an object in C # is represented by data fields.

Properties in C # are essentially methods that control the state of an object. Using them can lead to different states of deserialization objects, since the order in which the properties are set can affect the final state of the data. Other factors can lead to improper deserialization of the state if, for example, the method (set property) depends on some changing context, for example, the current DateTime.

Can you say what about encapsulation? I do not want my object to be in an invalid state, and I have to perform validation checks, integrity checks on the graph of objects, etc. Yes, you should, so we put the DataMember attributes in the details? No.

The problem is that many people mix two different things: DTO (data transfer object, WCF contract) with a domain entity. You need to make sure that the data you receive is the same data that was sent, and then make sure that you can create a valid domain from this data. The best way to achieve this is to use separate classes for the DTO and build an Entity object from them.

But most programmers are lazy, and they like to simply decorate Domain Entity with DataMemeber attributes. In this case, the Field or Prop solution depends on where your validation logic is, if your verification logic is buried in Set methods, you will have to use the details if it is extenral, you must use the fields and validate your domain object after desirialization.

PS I think that the same rules apply to any serialization process, such as a database.

In addition, I would like to mention that Silverlight cannot serialize \ deserialize private fields, because you cannot access them from the outside using reflection, and you have to make them private and use InternalsVisibleToAttribute.

Case 2

It's complicated. The focus here is on interoperability. At 99.9%, you will have separate DTO classes in this case and, most likely, many different versions to support old clients. It doesn't matter where you entered the DataMembers attributes, because you are using DTO. I will not understand this scenario because developers who work on such a large-scale system are usually quite experienced and they do not bother to read SO.

+4
Dec 09 '11 at 8:15
source share

In theory, and as long as you keep m_SomeValue always equal SomeValue (like a simple getter / setter), nothing. In addition to the variable name displayed by WCF. (Obviously, if you mark the variable m_ , then your proxy class will also have the same name m_ . The proxy class will generate a public property, regardless of whether you use a public / protected / internal / private field or property.

However, if you have any special logic in your accessories that can change the return value (for example, ToUpper() string, for example), you must return another value.

+3
Feb 17 '09 at 13:32
source share

Personally, I would just use the property and completely delete the member variable all together. i.e.

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

The property will inexplicably create a member variable behind the scenes.

+2
Oct 27 '09 at 16:34
source share

If you add [DataMember] to private int m_SomeValue, this member cannot be serialized, so you need to add it to public int SomeValue.

[DataMember]
private int m_SomeValue;

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

the code above cannot be obtained in the client if you use it through WCF.

+1
May 21 '10 at 3:08
source share



All Articles