WCF: DataMember attribute on property vs. member

后端 未结 7 2001
北海茫月
北海茫月 2021-01-30 20:27

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

private int m_SomeValue;

[DataMember]  
public int SomeVal         


        
相关标签:
7条回答
  • 2021-01-30 20:39

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

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

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

    0 讨论(0)
  • 2021-01-30 20:41

    In general, you should favor applying the DataMember attribute on the property, rather than on the private field. The only reason to apply the attribute to the field instead is if the property were read-only (i.e. it has no setter).

    0 讨论(0)
  • 2021-01-30 20:42

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

    However, if you have any special logic in your accessors that may modify the value returned (ToUpper()ing a string, for example), then you would return a different value.

    0 讨论(0)
  • 2021-01-30 20:44

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

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

    However, there may be some permissions issues accessing private members, in particular on silverlight and CF - in which case I would recommend using the public property as the data-member. Actually, I would tend to always use a property unless I had a very good reason...

    0 讨论(0)
  • 2021-01-30 20:51

    If add [DataMember] on private int m_SomeValue, this member can not be serialization,so must be add it on public int SomeValue.

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

    the code of above can not be get value in the client if you use it through WCF.

    0 讨论(0)
  • 2021-01-30 20:55

    This decission depends on the usage of you WCF service:

    1. Internal service consumed by you own .NET systems, that share the same Domain Model.
    2. External service consumed by different platforms, that do not share same Domain Model.

    Case 1.

    Serialization - is the process of persisting the state of the object. The state of the object in C# is represented by it's data fields.

    Properties in C# are essentially - methods, which manipulate the state of the object. Using them can result in different object state ofter deserialization, because the order in which properties are set can have impact on it's final data state. Other factors can result in incorrect state deserialization too, if for example method (property set) relies on some context that is changing, like current DateTime.

    You may say what about encapsulation? I don't want my object to be in invalid state, and I must do validation checks, object graph integrity checks, etc. Yes, you should, so we put the DataMember attribs on props? No.

    The problem here is that lot's of people mix two different things, DTO (Data Transfer Object, WCF Contract) with Domain Entity. What you need is ensure that the data you recieve is exectly the same data that was send, and then ensure that you can construct valid Domain Entity from this data. The best way to achieve this is use separate classes for DTO's, and construct Domain Entity from them.

    But most programmers are lazy, and they like to simple decorate Domain Entity with DataMemeber attributes. In this case the decision Field or Prop depends on where your validation logic is, if your validation logic is buried in Set methods, you will have to use Props, if it's extenral you should use Fields, and validate you Domain Entity after desirialization.

    P.S. I think the same rules apply to any serialization process, like data base persistnce.

    Also, I would like to mention that Silverlight can't serialize\deserialize private fields, because you can't access them from outside using reflection, and you will have to make them private and use InternalsVisibleToAttribute.

    Case 2.

    This is hard one. The main focus here is interoperability. In 99.9% you will have separate DTO classes in this case and most likely lot's of different versions of them to support old clients. It doesn't matter where you put DataMembers attribs in this, because you use DTO's. I will not bother with explaining this scenario, because developers who work on such large scale system are usually quite experienced, and they don't bother reading SO.

    0 讨论(0)
提交回复
热议问题