博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Web消息主体风格(Message Body Style)
阅读量:5101 次
发布时间:2019-06-13

本文共 6685 字,大约阅读时间需要 22 分钟。

对于Web HTTP编程模型来说,服务契约中作为操作的方法无须应用OperationContractAttribute特性,只需要根据需要应用WebGetAttribute与WebInvokeAttribute特性即可。前者针对GET HTTP方法,或者则针对其他HTTP方法。WebGetAttribute与WebInvokeAttribute的属性BodyStyle和IsBodyStyleSetExplicitly涉及到“Web消息主体风格”的话题。

1: [AttributeUsage(AttributeTargets.Method)]
2: public sealed class WebGetAttribute : Attribute, IOperationBehavior
3: {
4:     //其他成员
5:     public WebMessageBodyStyle BodyStyle { get; set; }
6: }
7: 
8: [AttributeUsage(AttributeTargets.Method)]
9: public sealed class WebInvokeAttribute : Attribute, IOperationBehavior
10: {
11:     //其他成员
12:     public WebMessageBodyStyle BodyStyle { get; set; }
13: }

至于消息主体的风格通过具有如下定义的枚举表示。

1: public enum WebMessageBodyStyle
2: {
3:     Bare,
4:     Wrapped,
5:     WrappedRequest,
6:     WrappedResponse
7: }

我们知道请求消息和回复消息分别是对操作方法输入参数和返回值(输出参数和引用参数)的封装,WebMessageBodyStyle中的Bare表示请求消息和回复消息的主体部分仅仅包含针对输入参数和返回值(输出参数和引用参数)序列化后的内容,而Wrapped则会在外面包装一个基于当前操作的“封套”。枚举项WrappedRequest和WrappedResponse用于单独针对请求消息和回复消息的主体进行封装。

WebGetAttribute与WebInvokeAttribute的属性BodyStyle的默认值为Bare。如果该属性被设置成WrappedRequest,则回复消息主体依然采用Bare风格;如果该属性被设置成WrappedResponse,则请求消息主体依然采用Bare风格。布尔类型的只读属性IsBodyStyleSetExplicitly表示是否针对属性BodyStyle进行了显示设置。

目录 

一、Xml+Bare 
二、Xml+Wrapped 
三、JSON+Bare 
四、JSON+Wrapped 
五、Bare请求消息风格对单一输入的限制 
六、Bare回复消息风格对单一输出的限制

一、Xml + Bare

我们通过来看看针对不同的消息格式(XML和JSON),请求消息和回复消息的主体在采用不同风格的情况下具有怎样的结构。现在我们对应用在契约接口IEmployees中的Create操作方法上的WebInvokeAttribute进行了如下的修改,即显式地指定了请求消息和回复消息的格式(XML)和主体风格(Bare)。同时也将返回类型从void编程了Employee,并直接将创建的Employee对象返回。

1: [ServiceContract]
2: public interface IEmployees
3: {
4:     //其他成员
5:     [WebInvoke(UriTemplate = "/", Method = "POST",
6:     RequestFormat = WebMessageFormat.Xml,
7:     ResponseFormat = WebMessageFormat.Xml,
8:     BodyStyle = WebMessageBodyStyle.Bare)]
9:     Employee Create(Employee employee);
10: }
11: 
12: public class EmployeesService : IEmployees
13: {
14:     //其他成员
15:     public Employee Create(Employee employee)
16:     {
17:         employees.Add(employee);
18:         return employee;
19:     }
20: }

我们针对如下所示的代码通过服务调用添加一个姓名为“王五”的员工。

1: using (ChannelFactory
channelFactory = new ChannelFactory
("employeeService"))
2: {
3:     IEmployees proxy = channelFactory.CreateChannel();
4:     proxy.Create(new Employee
5:     {
6:         Id         = "003",
7:         Name       = "王五",
8:          Grade     = "G9",
9:         Department = "行政部"
10:     });
11: }

针对如上所示的服务调用,由于消息格式和主体风格分别为Xml和Bare,所以作为请求消息和回复消息的主体仅仅是Employee对象被序列化后生成的XML片断,具体内容如下所示。

1: 请求消息主体:
2: 
3:   xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
4:   
行政部
5:   
G9
6:   
003
7:   
王五
8: 
9: 
10: 回复消息主体:
11: 
12:   xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
13:   
行政部
14:   
G9
15:   
003
16:   
王五
17: 

二、Xml + Wrapped

现在我们对契约接口略加修改,将应用在操作方法Create上的WebInvokeAttribute特性的属性BodyStyle设置为Wrapped。

1: [ServiceContract]
2: public interface IEmployees
3: {
4:     //其他成员
5:     [WebInvoke(UriTemplate = "/", Method = "POST",
6:     RequestFormat = WebMessageFormat.Xml,
7:     ResponseFormat = WebMessageFormat.Xml,
8:     BodyStyle = WebMessageBodyStyle.Wrapped)]
9:     Employee Create(Employee employee);
10: }

针对相同的服务调用,请求消息和回复消息将具有如下所示的主体内容。我们可以看出Employee被序列化后生成的XML在请求消息中作为<Create>元素的子元素;对于回复消息来说,Employee被序列化后生成的XML的根元素名称为CreateResult,而不是<Employee>,而整个<CreateResult>内嵌于< CreateResponse >元素中。

1: 请求消息主体:
2: 
3:   
4:         xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
5:     
行政部
6:     
G9
7:     
003
8:     
王五
9:   
10: 
11: 
12: 回复消息主体:
13: 
14:   
15:         xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
16:     
行政部
17:     
G9
18:     
003
19:     
王五
20:   
21: 

三、JSON+ Bare

上面我们通过实例演示了消息格式为Xml情况下针对不同风格的消息主体的内容差异,现在我们按照相同的方式来讨论当消息格式为JSON的时候,针对不同风格的消息主体在结构上又具有怎样差异。如下面的代码片断所示,我们通过对契约接口的修改将服务操作Create的消息格式和主体风格设置成Json和Bare。

1: [ServiceContract]
2: public interface IEmployees
3: {
4:     //其他成员
5:     [WebInvoke(UriTemplate = "/", Method = "POST",
6:     RequestFormat = WebMessageFormat.Json,
7:     ResponseFormat = WebMessageFormat.Json,
8:     BodyStyle = WebMessageBodyStyle.Bare)]
9:     Employee Create(Employee employee);
10: }

同样针对之前的服务调用,以JSON形式表示的Employee对象将直接作为请求消息和回复消息的主体部分,具体的内容如下所示。(S1004)

1: 请求消息主体:
2: {"Department":"行政部","Grade":"G9","Id":"003","Name":"王五"}
3: 
4: 回复消息主体:
5: {"Department":"行政部","Grade":"G9","Id":"003","Name":"王五"}

四、JSON+ Wrapped

我们最后来演示Json消息格式在Wrapped风格下具有怎样的结构,为此我们只需要将应用在Create操作方法上的WebInvokeAttribute特性的BodyStyle属性设置为Wrapped。

1: [ServiceContract]
2: public interface IEmployees
3: {
4:     //其他成员
5:     [WebInvoke(UriTemplate = "/", Method = "POST",
6:     RequestFormat = WebMessageFormat.Json,
7:     ResponseFormat = WebMessageFormat.Json,
8:     BodyStyle = WebMessageBodyStyle.Wrapped)]
9:     Employee Create(Employee employee);
10: }

如下面的代码所示,由于请求消息和回复消息采用Wrapped风格,表示Employee的JSON对象最终作为最终JSON对象的“employee”属性和“CreateResult”属性。(S1005)

1: 请求消息主体:
2: {"employee":{"Department":"行政部","Grade":"G9","Id":"003","Name":"王五"}}
3: 
4: 回复消息主体:
5: {"CreateResult":{"Department":"行政部","Grade":"G9","Id":"003","Name":"王五"}}

五、Bare请求消息风格对单一输入的要求

对于Bare消息主体风格来说,意味着对象被序列化后生成的XML或者JSON表示直接作为消息的主体,所以只适用于单一对象。具体来说,只有具有唯一输入参数的操作方法才能将请求消息的主题风格设置为Bare。

1: [ServiceContract(Namespace = "http://www.artech.com/")]
2: public interface ICalculator
3: {
4:     [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare)]
5:     double Add( double x,  double y);
6: }

如上所示的是我们熟悉的计算服务的契约接口的定义。消息主体风格为Bare的操作方法Create具有两个输入参数(x和y),在对实现了该契约接口进行寄宿的时候就会抛出如下图所示的InvalidOperationException异常,提示“约定“ICalculator”的操作‘Add’指定要序列化多个请求正文参数,但没有任何包装元素。如果没有包装元素,至多可序列化一个正文参数。请删除多余的正文参数,或将 WebGetAttribute/WebInvokeAttribute 的 BodyStyle 属性设置为 Wrapped”。

六、Bare回复消息风格对单一输出的要求

由于回复参数是对返回值、引用参数和输出参数的封装,所以当操作方法具有引用参数或者输出参数时不能将回复消息的主体风格设置为Bare。

1: [ServiceContract(Namespace = "http://www.artech.com/")]
2: public interface ICalculator
3: {
4:     [WebInvoke(BodyStyle = WebMessageBodyStyle.WrappedRequest)]
5:     void Add( double x,  double y, out double result);
6: }

同样以计算服务契约为例,现在我们通过如上的方式以输出参数的形式返回加法运算的结果,并将应用在操作方法上的WebInvokeAttribute特性的BodyStyle属性设置为WrappedRequest,这意味着请求消息和回复消息分别采用Wrapped和Bare风格。当我们对实现了该契约接口的服务设施寄宿时会抛出下图所示的InvalidOperationException异常,并提示“约定‘ICalculator’的操作‘Add’至少指定一个响应正文参数不是操作的返回值。当 WebGetAttribute/WebInvokeAttribute 的 BodyStyle 属性设置为 Bare 时,只允许使用返回值。请删除多余的响应正文参数或将 BodyStyle 属性设置为 Wrapped”。

 

 
 

转载于:https://www.cnblogs.com/soundcode/p/4036194.html

你可能感兴趣的文章
struts2文件下载及文件名中文问题
查看>>
使用原生Java代码生成可执行Jar包
查看>>
<轉>APUE:mmap函数
查看>>
网站结构优化
查看>>
IFrame与window对象(contentWindow)
查看>>
19、Flask实战第19天:CSRF攻击与防御
查看>>
Shell Notes(2)
查看>>
ArcGIS Engine开发前基础知识(3)
查看>>
阮老师谈虚数
查看>>
Android Support兼容包详解
查看>>
Socket通信案例
查看>>
2015/7/24 (等待回调,结果是盘中回调,盘末拉升,错过了进仓机会吗?详情进入...
查看>>
Delphi XE7的安卓程序如何调用JAVA的JAR,使用JAVA的类?
查看>>
对 NGUI 子节点的位置的一点理解
查看>>
[LeetCode] Search in Rotated Sorted Array [35]
查看>>
仙剑---相爱
查看>>
UNIX网络编程卷1 时间获取程序server UDP 协议无关
查看>>
OCP-1Z0-051-名称解析-文章12称号
查看>>
CDH秘籍(两):cloudera Manager存储监控数据
查看>>
linux signal 处理
查看>>