WCF 中的 DataContract 与 MessageContract






4.85/5 (10投票s)
WCF 中的 DataContract 与 MessageContract
在 WCF 中,DataContract 是服务和客户端之间的一种约定,用于描述他们之间将交换的数据类型。另一方面,MessageContract 描述了在服务和客户端之间传递的 SOAP 消息的结构。使用 DataContract,我们实际上控制 SOAP 消息的内容(即有效负载数据或消息体),而 MessageContract 提供对 SOAP 消息结构的完全控制。
在 Windows Communication Foundation 中,有两种类型的契约:
在 Windows Communication Foundation 中,有两种类型的契约:
- 行为契约
- 结构契约
DataContract
和 MessageContract
都是结构契约,它们相互补充,服务于不同的目的。要更详细地了解 WCF 中的契约,请参阅我的 WCF 常见问题解答教程 - 第一部分。现在我们通过一个例子来理解 DataContract
和 MessageContract
之间的区别。DataContract 示例
考虑一个具有以下操作的 WCF 服务:
[ServiceContract()]
public interface IStudentService
{
[OperationContract()]
StudentInfo GetStudentById(int studentId);
}
这里,返回类型是 StudentInfo
,它基本上是一个定义如下的 CLR 类型作为 DataContract
。 [DataContract(Namespace="http://www.something.com/students/")]
public class StudentInfo
{
[DataMember(Name="StudentId", Order=1)]
public int ID;
[DataMember(Name="FirstName", Order=2)]
public string FName;
[DataMember(Name="LastName", Order=3)]
public string LName;
}
当调用服务方法时,此 StudentInfo
类型将作为 SOAP 响应消息体的一部分返回。
如果我们查看这个“
StudentInfo
”DataContract,我们提供了关于传回给消费者的数据的各种细节。例如:Order
= 1,2,3 定义了响应消息体中数据成员的顺序。Name
= "some name" 规定了响应消息体中特定数据成员的名称。
但是通过所有这些属性,我们实际上只控制 SOAP 消息体的内容。在大多数情况下,开发人员关心的是控制消息的主体部分,而不是整个 SOAP 消息。
MessageContract 示例
正如我们在上面的例子中所看到的,
现在考虑一个业务场景,需要身份验证代码才能访问我们的服务,即
查看此场景的以下实现:
DataContract
对 SOAP 消息的控制有限,并且所有控制都与 SOAP 消息体内的内容相关。但是,在某些情况下,我们需要对 SOAP 消息进行更多的控制。因此,MessageContract
在这种情况下是答案。现在考虑一个业务场景,需要身份验证代码才能访问我们的服务,即
IStudentService
。在这种情况下,我们提供的功能保持不变,但身份验证代码的有效性现在是额外的先决条件。因此,在这种情况下,SOAP 消息头是存储身份验证代码的最佳位置,同时调用服务方法。查看此场景的以下实现:
[MessageContract(IsWrapped = false)]
public class StudentInfoRequestMessage
{
[MessageHeader()]
public string AuthCode;
[MessageBodyMember()]
public int StudentId;
}
[MessageContract(IsWrapped = false)]
public class StudentInfoResponseMessage
{
[MessageBodyMember()]
public StudentInfo MyStudentInfo;
}
[ServiceContract]
public interface IStudentService
{
[OperationContract]
StudentInfoResponseMessage GetStudentById(StudentInfoRequestMessage stdInfoMessage);
}
public class StudentService : IStudentService
{
public StudentInfoResponseMessage GetStudentById(StudentInfoRequestMessage stdInfoMessage)
{
private const string AuthCode = "ali123salman";
//Validation Check
if (stdInfoMessage.AuthCode != AuthCode)
{
//fault response
}
//routine code
}
}
希望现在读者对 WCF 中 DataContract
和 MessageContract
之间的区别有很好的理解。