WCF Messaging Fundamentals 的学习笔记

读了Aaron Skonnard MSDN杂志的文章,做一些记录,文笔很不错,将WCF的许多概念讲得简单明了,看完了,让人感觉意犹未尽的感觉

 

1. 建立一个MTOM的消息

 

// write to MTOM representation
FileStream custMtomStream = new FileStream(
"customer.mtom", FileMode.Create);
using (XmlWriter xw = XmlDictionaryWriter.CreateMtomWriter(
custMtomStream, Encoding.UTF8, 1024, "text/xml"))
{
doc.WriteTo(xw);
}

// read from MTOM representation
XmlDocument doc = new XmlDocument();
FileStream custMtomStream = new FileStream(
    "customer.mtom", FileMode.Open);
using (XmlReader xr = XmlDictionaryReader.CreateMtomReader(
    custMtomStream, Encoding.UTF8, XmlDictionaryReaderQuotas.Max))
{
    doc.Load(xr);
}

 

// write to text (XML 1.0) representation
doc.Save("customer.xml");

 

 

 

2. Message(System.ServiceModel.Channels.Message) 类在本质上模拟消息正文以及消息标头和属性的集合。可用方法主要用于创建消息、读写消息正文以及操作标头和属性的集合。

 

3. WS-Addressing 是一种规范,用于扩展 SOAP 以提供与传输无关的机制来寻址/路由 SOAP 消息

4. 通过调用各种静态 CreateMessage重载之一创建 Message 对象,并使用 IDisposable 或通过显式调用 Close 处理 Message 对象。可以从头开始创建新的 Message 对象,在发送消息时通常这样做。也可以从消息流创建新的 Message 对象,在接收消息时通常这样做。

 

5. 如果从头开始创建消息,则必须指定操作、消息版本以及要在消息中使用的正文。操作唯一地标识消息的目的或语义。WCF 服务依赖于将传入消息分派给相应方法的操作。消息版本标识传输时使用的 SOAP 和 WS-Addressing 版本(如果有)。指定消息版本时可以选择各种不同的选项

 

6. 在希望写入消息时,可以通过分别调用 WriteMessage 或 WriteBody 方法写入整个消息或仅写入正文。这两种方法都具有允许提供 XmlDictionaryWriter 或 XmlWriter 对象的重载

 

7. 通过 MessageVersion 类,可以指定要使用的 SOAP 和 WS-Addressing 版本。通过调用 CreateVersion 并提供 EnvelopeVersion 对象(用于标识 SOAP 版本)和 AddressingVersion 对象(用于标识 WS-Addressing 版本),可以创建 MessageVersion 对象

 

8. EnvelopeVersion.None 指定在传输过程中您不希望使用 SOAP,它还要求您使用 AddressingVersion.None。这是希望在传统的 XML 消息传递方案中利用 Windows Communication Foundation 时的常见设置。Soap11 表示 SOAP 1.1 规范,该规范目前得到广泛使用,而 Soap12 表示 SOAP 1.2 W3C 推荐标准(有关指向这两种规范的链接,请参阅 www.w3.org/TR/soap)。

 

9. WSAddressingAugust2004 表示 2004 年 8 月开始提交的 WS-Addressing W3C 提案(请参阅 www.w3.org/Submission/ws-addressing),目前得到广泛支持。而 WSAddressing10 表示最终的 WS-Addressing 1.0 W3C 推荐标准(请参阅 www.w3.org/2002/ws/addr)。

 

10. Message 对象在开始时处于 Created 状态,该状态是处理正文的唯一有效状态。处理正文有以下几种不同的方式:可以对其进行读取、写入或复制。调用 GetReaderAtBodyContents 或 GetBody<T> 可将状态更改为 Read。调用 WriteMessage 或 WriteBody 可将状态更改为 Written。调用 CreateBufferedCopy 可将状态更改为 Copied
在 Message 对象不再处于 Created 状态后,需要访问正文的任何方法都将引发异常。例如,首次调用 GetBody<T> 后再次调用它将导致异常。在需要多次处理正文的情况下,可以创建缓冲副本(通过调用 CreateBufferedCopy)或者将正文加载到 XmlDocument 中或将它反序列化为 .NET 对象以便在内存中使用。

 

11. 与标头(它始终在消息中传输)不同,消息属性通常仅在本地处理期间使用(它们可能不对通信时发生的情况产生影响,尽管有时它们会产生影响)。例如,使用 HTTP 时,Windows Communication Foundation 在传入 Message 对象的 Properties 集合中存储 HTTP 请求详细信息。详细信息存储在 HttpRequestMessageProperty 类型的对象(可以使用属性名的 httpRequest 访问它)中。还可以通过用 HttpReponseMessageProperty 类型的对象填充名为 httpResponse 的属性,影响 HTTP 响应详细信息。

 

12. Windows Communication Foundation 通道(尤其是实现各种 WS-* 规范的内置协议通道)层中的组件频繁使用标头和属性是很常见的。

 

13. 将消息映射到方法-必须首先定义将传入消息映射到方法的服务约定,才能开始使用WCF发送或接收消息。通过使操作值与方法签名关联,可以做到这一点
[OperationContract(Action="*")]
void ProcessMessage(Message msg);
此定义使 ProcessMessage 与所有传入消息关联,而不管其操作值如何(由于使用了 Action= "*" 子句)

 

还可以通过将 Action 属性设置为特定值(如 urn:add-customer)使方法与特定操作值关联
[OperationContract(Action="urn:add-customer")]
void AddCustomer(Message msg);
在WCF收到传入消息时,它将查看操作以确定要调度的方法,然后它再执行任何必要的序列化。对请求/响应类型使用消息时,WCF不执行任何序列化,而是由您决定如何处理消息。但是,使用键入的签名时,WCF使用序列化方法在后台自动执行读写消息正文的过程

 

[OperationContract(Action="urn:add-customer")]
void AddCustomer(Customer cust);
在这种情况下,WCF负责在调用 AddCustomer之前将传入消息的正文反序列化为 Customer 对象。

 

14. 为了设置WCF 服务
1.必须通知它要使用的传输和地址。
2.必须指定所需的 XML 表示形式和消息版本。
3.必须配置采用哪些 WS-* 协议。
4.必须提供传入消息和服务方法之间的映射
在WCF中是使用Endpoints

15. 端点(Endpoint)配置仅仅是地址、绑定和约定的组合(an address, binding, and contra)。约定(contract)定义消息和方法之间的映射。绑定(binding)指定剩余的消息传递详细信息。它指定在传递期间要使用的传输、XML 表示形式和消息版本。它还确定生成通道堆栈时应该包括的 WS-* 协议。

 

绑定还指定消息编码器(message encoder);它实际上控制 XML 表示形式和消息版本详细信息。在运行时,消息编码器是传输通道从数据流读取和向其写入消息所用的组件。WCF提供了三个内置的消息编码器实现:TextMessageEncoder、BinaryMessageEncoder 和 MtomMessageEncoder

 

原文:
https://msdn.microsoft.com/msdnmag/issues/07/04/ServiceStation/default.aspx?loc=en
https://msdn.microsoft.com/msdnmag/issues/07/04/ServiceStation/default.aspx?loc=zh