Web消息主体风格(Message Body Style)

简介:

对于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: }

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

   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<IEmployees> channelFactory = new ChannelFactory<IEmployees>("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: <Employee xmlns="http://www.artech.com/" 
   3:   xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   4:   <Department>行政部</Department>
   5:   <Grade>G9</Grade>
   6:   <Id>003</Id>
   7:   <Name>王五</Name>
   8: </Employee>
   9:  
  10: 回复消息主体:
  11: <Employee xmlns="http://www.artech.com/" 
  12:   xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  13:   <Department>行政部</Department>
  14:   <Grade>G9</Grade>
  15:   <Id>003</Id>
  16:   <Name>王五</Name>
  17: </Employee>

二、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: <Create xmlns="http://tempuri.org/">
   3:   <employee xmlns:a="http://www.artech.com/" 
   4:         xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   5:     <a:Department>行政部</a:Department>
   6:     <a:Grade>G9</a:Grade>
   7:     <a:Id>003</a:Id>
   8:     <a:Name>王五</a:Name>
   9:   </employee>
  10: </Create>
  11:  
  12: 回复消息主体:
  13: <CreateResponse xmlns="http://tempuri.org/">
  14:   <CreateResult xmlns:a="http://www.artech.com/" 
  15:         xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  16:     <a:Department>行政部</a:Department>
  17:     <a:Grade>G9</a:Grade>
  18:     <a:Id>003</a:Id>
  19:     <a:Name>王五</a:Name>
  20:   </CreateResult>
  21: </CreateResponse>

三、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”。

image

六、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”。

image

 

 
  分类:  Restful , WCF
本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/4036194.html ,如需转载请自行联系原作者
相关文章
|
开发框架 中间件 .NET
分享 ASP.NET Core Web Api 中间件获取 Request Body 两个方法
分享 ASP.NET Core Web Api 中间件获取 Request Body 两个方法
595 0
|
JavaScript 前端开发 定位技术
Rest风格WEB服务(Rest Style Web Service)的真相
Rest风格WEB服务(Rest Style Web Service)的真相
278 1
|
Web App开发 JavaScript 前端开发
Rest风格WEB服务(Rest Style Web Service)的真相
写这篇文章是目的不是介绍Web-Service, 而是从Restful Web Service说起来剖析一下 什么才是真正的Restful Style的架构与协议,从而更好的理解web服务的设计理念与架 构本质。
1355 0
|
24天前
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
131 4
|
5月前
|
缓存 JavaScript 前端开发
鸿蒙5开发宝藏案例分享---Web开发优化案例分享
本文深入解读鸿蒙官方文档中的 `ArkWeb` 性能优化技巧,从预启动进程到预渲染,涵盖预下载、预连接、预取POST等八大优化策略。通过代码示例详解如何提升Web页面加载速度,助你打造流畅的HarmonyOS应用体验。内容实用,按需选用,让H5页面快到飞起!
|
5月前
|
JavaScript 前端开发 API
鸿蒙5开发宝藏案例分享---Web加载时延优化解析
本文深入解析了鸿蒙开发中Web加载完成时延的优化技巧,结合官方案例与实际代码,助你提升性能。核心内容包括:使用DevEco Profiler和DevTools定位瓶颈、四大优化方向(资源合并、接口预取、图片懒加载、任务拆解)及高频手段总结。同时提供性能优化黄金准则,如首屏资源控制在300KB内、关键接口响应≤200ms等,帮助开发者实现丝般流畅体验。
|
前端开发 JavaScript Shell
鸿蒙5开发宝藏案例分享---Web页面内点击响应时延分析
本文为鸿蒙开发者整理了Web性能优化的实战案例解析,结合官方文档深度扩展。内容涵盖点击响应时延核心指标(≤100ms)、性能分析工具链(如DevTools时间线、ArkUI Trace抓取)以及高频优化场景,包括递归函数优化、网络请求阻塞解决方案和setTimeout滥用问题等。同时提供进阶技巧,如首帧加速、透明动画陷阱规避及Web组件初始化加速,并通过优化前后Trace对比展示成果。最后总结了快速定位问题的方法与开发建议,助力开发者提升Web应用性能。
|
5月前
|
JSON 开发框架 自然语言处理
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(三)
本文主要介绍了应用开发中的三大核心内容:生命周期管理、资源限定与访问以及多语言支持。在生命周期部分,详细说明了应用和页面的生命周期函数及其触发时机,帮助开发者更好地掌控应用状态变化。资源限定与访问章节,则聚焦于资源限定词的定义、命名规则及匹配逻辑,并阐述了如何通过 `$r` 引用 JS 模块内的资源。最后,多语言支持部分讲解了如何通过 JSON 文件定义多语言资源,使用 `$t` 和 `$tc` 方法实现简单格式化与单复数格式化,为全球化应用提供便利。
230 104
|
5月前
|
JavaScript 前端开发 API
【HarmonyOS Next之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(二)
本文介绍了HarmonyOS应用开发中的HML、CSS和JS语法。HML作为标记语言,支持数据绑定、事件处理、列表渲染等功能;CSS用于样式定义,涵盖尺寸单位、样式导入、选择器及伪类等特性;JS实现业务逻辑,包括ES6语法支持、对象属性、数据方法及事件处理。通过具体代码示例,详细解析了页面构建与交互的实现方式,为开发者提供全面的技术指导。
244 104

热门文章

最新文章

下一篇
开通oss服务