.net WCF:属性与成员上的 DataMember 属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/556775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:09:18  来源:igfitidea点击:

WCF: DataMember attribute on property vs. member

.netwcfserialization

提问by Julien Poulin

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

在 wcf 中,在DataMember属性上应用属性有 什么区别

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 {...}
}

?

?

采纳答案by dthrasher

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).

通常,您应该倾向于在属性上应用 DataMember 特性,而不是在私有字段上应用。将该属性应用到字段的唯一原因是该属性是只读的(即它没有 setter)。

回答by Marc Gravell

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

只要您使用Name标记,无论使用字段还是属性,合同都是相同的。

[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 alwaysuse a property unless I had a very good reason...

但是,访问私有成员可能存在一些权限问题,特别是在 Silverlight 和 CF 上 - 在这种情况下,我建议使用公共属性作为数据成员。实际上,除非我有很好的理由,否则我倾向于始终使用属性...

回答by Walter Almeida

There are good reasons you may want to mark fields rather than properties as DataMember .

您可能有充分的理由希望将字段而不是属性标记为 DataMember 。

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

请查看更多详细信息:http: //blog.walteralmeida.com/2010/05/wcf-and-datacontract-serialization-internals-and-tips-.html

By the way: ContractSerializers will serialize any private field that has the DataMemberAttribute on it only if running in full trust environment. Does not work in partial trust (check the blog listed above for a solution)

顺便说一句:只有在完全信任环境中运行时,ContractSerializers 才会序列化任何具有 DataMemberAttribute 的私有字段。在部分信任下不起作用(查看上面列出的博客以获取解决方案)

回答by Alex Burtsev

This decission depends on the usage of you WCF service:

此决定取决于您 WCF 服务的使用情况:

  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.
  1. 您拥有的 .NET 系统使用的内部服务共享相同的域模型。
  2. 不同平台使用的外部服务,不共享相同的领域模型。

Case 1.

情况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.

序列化 - 是保持对象状态的过程。C# 中对象的状态由它的数据字段表示。

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.

C# 中的属性本质上是方法,它们操作对象的状态。使用它们可能会导致反序列化后的对象状态不同,因为设置属性的顺序可能会影响其最终数据状态。其他因素也可能导致不正确的状态反序列化,例如,如果方法(属性集)依赖于某些正在更改的上下文,例如当前的 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.

你可能会说封装呢?我不希望我的对象处于无效状态,我必须进行验证检查、对象图完整性检查等。是的,您应该这样做,所以我们将 DataMember 属性放在道具上?不。

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.

这里的问题是很多人混合了两种不同的东西,DTO(数据传输对象,WCF 合同)和域实体。您需要的是确保您收到的数据与发送的数据完全相同,然后确保您可以根据这些数据构建有效的域实体。实现这一点的最佳方法是为 DTO 使用单独的类,并从它们构造域实体。

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.

但是大部分程序员都是懒惰的,他们喜欢简单地用DataMemeber属性来装饰Domain Entity。在这种情况下,决定 Field 或 Prop 取决于您的验证逻辑在哪里,如果您的验证逻辑隐藏在 Set 方法中,您将不得不使用 Props,如果它是外部的,您应该使用 Fields,并在反序列化后验证您的域实体。

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

PS 我认为相同的规则适用于任何序列化过程,如数据库持久性。

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.

另外,我想提一下 Silverlight 无法序列化/反序列化私有字段,因为您无法使用反射从外部访问它们,您必须将它们设为私有并使用 InternalsVisibleToAttribute。

Case 2.

案例 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.

这是很难的。这里的主要焦点是互操作性。在 99.9% 的情况下,您将拥有单独的 DTO 类,并且很可能会有很多不同版本的它们来支持旧客户端。您将 DataMembers 属性放在何处并不重要,因为您使用的是 DTO。我不会费心解释这种情况,因为在如此大规模系统上工作的开发人员通常很有经验,他们不会费心阅读 SO。

回答by Jarrett Meyer

In theory, and as long as you keep m_SomeValuealways 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.

从理论上讲,只要您m_SomeValue始终保持等于SomeValue(就像一个简单的 getter/setter),就什么都没有。除了 WCF 公开的变量的名称。(显然,如果您标记m_变量,那么您的代理类也将具有相同的m_名称。无论您使用 public/protected/internal/private 字段或属性,代理类都会生成一个公共属性。

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.

但是,如果您的访问器中有任何特殊的逻辑可以修改返回的值(ToUpper()例如,字符串),那么您将返回一个不同的值。

回答by bj.

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

就我个人而言,我只会使用该属性并完全删除成员变量。IE

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

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

该属性会莫名其妙地在幕后创建一个成员变量。

回答by shawdren

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

如果在private int m_SomeValue 上添加[DataMember],则该成员不能被序列化,因此必须将其添加到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.

如果通过 WCF 使用,上面的代码无法在客户端获取值。