【问题标题】:Basics of DataContractAttributeDataContractAttribute 基础知识
【发布时间】:2013-04-10 22:00:33
【问题描述】:

我正在查看 Microsoft 的操作方法:Create a Basic Data Contract for a Class or Structure,但它给我留下了很多问题。

他们提供了这个非常简单的例子:

using System;
using System.Runtime.Serialization;

[DataContract]
public class Person
{
  // This member is serialized.
  [DataMember]
  internal string FullName;

  // This is serialized even though it is private.
  [DataMember]
  private int Age;

  // This is not serialized because the DataMemberAttribute 
  // has not been applied.
  private string MailingAddress;

  // This is not serialized, but the property is.
  private string telephoneNumberValue;

  [DataMember]
  public string TelephoneNumber
  {
    get { return telephoneNumberValue; }
    set { telephoneNumberValue = value; }
  }
}

就我而言,我还需要包含另一个名为 ADUser(Active Directory 用户)的自定义类对象。

我知道ADUser 必须用DataContractAttribute 标记,但我不知道具体该怎么做。

这里又是微软的课程,但这次添加了ADUser 字段:

using System;
using System.Runtime.Serialization;

[DataContract]
public class Person
{
  // This member is serialized.
  [DataMember]
  internal string FullName;

  // This is serialized even though it is private.
  [DataMember]
  private int Age;

  // This is not serialized because the DataMemberAttribute 
  // has not been applied.
  private string MailingAddress;

  // This is not serialized, but the property is.
  private string telephoneNumberValue;

  [DataMember]
  public string TelephoneNumber
  {
    get { return telephoneNumberValue; }
    set { telephoneNumberValue = value; }
  }

  [DataMember]
  public ADUser UserInfo { get; set; }

}

我不太了解我的ADUser 班级需要如何或做什么,但我确信private 的内容可以保持不变。

我需要如何修复这个 ADUser 类示例?

public class ADUser
{

  private string first, last, loginID;

  public ADUser() {
    first = null;
    last = null;
    loginID = null;
  }

  private void getInfo() {
    // code goes here
    // which sets loginID;
  }

  public void SetName(string first, string last) {
    this.first = first;
    this.last = last;
    getInfo();
  }

  public string LoginID { get { return loginID; } }

}

【问题讨论】:

  • 您是否尝试将DataMember 放入AdUser 中的每个字段并用DataContract 标记ADUser
  • 正如@outcoldman 所说,只需要为ADUser 做同样的事情。基本上,DataContact 中的每个 DataMember 都需要是可序列化的,这意味着,如果有一个类,它也需要是一个 DataContact。另外,需要确保类有一个不需要参数的构造函数
  • 就这么简单?好的! :)

标签: c# wcf datacontractserializer datacontract


【解决方案1】:

正如@outcoldman@EthanLi 建议的那样:

  1. [DataContract] 属性添加到ADUser 类。

  2. 添加一个public构造函数不带参数。

  3. 选择要通过 WCF 传递的字段。用[DataMember] 属性标记所有这些。

  4. 只有 getter 的属性在序列化期间会失败:所有公开的属性都应该有 getter 和(公共!)setter。因此,例如,如果您尝试对其应用 [DataMember] 属性,您的 LoginID 属性将失败。在这种情况下,请考虑将其更改为方法。

【讨论】:

  • Microsoft 自动创建的某些内容具有 [ServiceContract][OperationContract] 成员以及与之对应的 [DataContract]。如果我的ADUser 不会成为服务,我是否也需要包含其中的任何内容?
  • [ServiceContract] 是你的服务,[OperationContract] - 你的方法
  • 这个答案不太正确。步骤#2 是不必要的。在步骤#4(不是真正的步骤,但无论如何)中,getter 和 setter 都不需要是public。当使用DataContractSerializer(如 WCF 所做的那样)时,可访问性被忽略(public vs private),并且序列化程序在反序列化时不使用任何构造函数,因此是否存在无参数构造函数并不重要。请注意,这与其他序列化程序不同,例如XmlSerializer.