【转】[WCF REST] 帮助页面与自动消息格式(JSON/XML)选择
可以说WebHttpBinding和WebHttpBehavior是整个Web HTTP编程模型最为核心的两个类型,前者主要解决消息编码问题,而余下的工作基本上落在了终结点行为WebHttpBehavior上。WebHttpBehavior属性HelpEnabled和AutomaticFormatSelectionEnabled是“帮助页面”与“自动消息格式选择”这两个特性的总开关。[“自动消息格式(JSON/XML)选择”源代码从这里下载]
1: public class WebHttpBehavior : IEndpointBehavior, ...
2: {
3: //其他成员
4: public virtual bool HelpEnabled { get; set; }
5: public virtual bool AutomaticFormatSelectionEnabled { get; set; }
6: }
一、 帮助页面
WCF 4.0为REST服务提供了帮助页面功能,我们可以通过浏览器访问服务帮助页面的地址得到所有操作的基本信息。但是这个功能在默认的情况下是关闭的,我们需要通过应用在终结点上的WebHttpBehavior行为的HelpEnabled属性开启该功能。
1: <configuration>
2: <system.serviceModel>
3: <behaviors>
4: <endpointBehaviors>
5: <behavior>
6: <webHttp helpEnabled="true" />
7: </behavior>
8: </endpointBehaviors>
9: </behaviors>
10: <services>
11: <service name="Artech.WcfServices.Service.EmployeesService">
12: <endpoint address="http://127.0.0.1:3721/employees"
13: binding="webHttpBinding"
14: contract="Artech.WcfServices.Service.Interface.IEmployees"/>
15: </service>
16: </services>
17: </system.serviceModel>
18: </configuration>
同样以之前演示的EmployeesService为例,我们通过如上的配置将终结点行为WebHttpHehavior应用在服务唯一的终结点上(默认终结点),并将HelpEnabled属性设置为True。那么基于终结点的帮助页面将以地址{终结点地址}/Help发布出来,我们通过浏览器访问这个地址就会得到如下图所示帮助页面。
如上图所示,帮助页面列出了包括相对地址、HTTP方法和基本描述在内的所有操作的基本信息。我们通过点击HTTP方法对应的链接可以获得包括基于相应格式(Xml和Json)消息结构(Schema)和实例。在默认的情况下,帮助页面中表示操作描述信息的格式为“Service at {操作地址}”,我们可以在定义服务契约的时候再操作方法上应用特性DescriptionAttribute来定义出现在帮助页面中的描述信息。
1: [ServiceContract]
2: public interface IEmployees
3: {
4: [WebGet(UriTemplate = "all")]
5: [Description("获取所有员工列表")]
6: IEnumerable<Employee> GetAll();
7:
8: [WebGet(UriTemplate = "{id}")]
9: [Description("获取指定ID的员工")]
10: Employee Get(string id);
11:
12: [WebInvoke(UriTemplate = "/", Method = "POST")]
13: [Description("创建一个新的员工")]
14: Employee Create(Employee employee);
15:
16: [WebInvoke(UriTemplate = "/", Method = "PUT")]
17: [Description("修改现有员工信息")]
18: void Update(Employee employee);
19:
20: [WebInvoke(UriTemplate = "{id}", Method = "DELETE")]
21: [Description("删除指定ID的员工")]
22: void Delete(string id);
23: }
如上面的代码片断所示,我们在契约接口IEmployees中的所有操作方法上应用了DescriptionAttribute特性并指定了相应的描述信息。这些描述信息就是出现在如下图所示的帮助页面中。
二、 自动消息格式选择
REST服务具有两种基本的消息格式(Xml和Json)。在定义服务契约的时候,我们可以通过应用在操作方法上的WebGetAttribute和WebInvokeAttribute指定回复消息的格式。如果没有通过这种方式对消息格式进行显式设置,我们还可以通过终结点行为WebHttpBehavior为回复消息设置一个默认的消息格式。除了这种显示设置方式之外,WCF还提供一种自动消息格式选择机制。
所谓消息格式的自动选择,就是服务根据请求消息来选择一种适合的格式进行消息的序列化。在默认的情况下,这种自动选择机制是关闭的,我们需要通过WebHttpBehavior的AutomaticFormatSelectionEnabled属性开启该机制。具体的消息格式选择机制策略(顺序)如下:
- 如果作为请求的HTTP消息具有Accept报头,则根据该报头决定回复消息的格式;
- 如果作为请求的HTTP消息具有Content-Type报头,则根据该报头决定回复消息的格式;
- 如果在定义服务契约时通过WebGetAttribute或者WebInvokeAttribute对回复消息的格式进行了显式设置,则采用该消息格式;
- 如果通过终结点行为WebHttpBehavior设置了对回复消息的格式进行了显式设置,则采用该消息格式;
- 采用默认消息格式Xml(WebMessageFormat枚举的默认值)。
我们同样通过之前创建的EmployeesService的实例来演示消息格式的自动选择机制。如下面的配置片断所示,我们将WebHttpBehavior行为应用到了寄宿服务的唯一终结点上,并且将AutomaticFormatSelectionEnabled属性设置为True。
1: <configuration>
2: <system.serviceModel>
3: <behaviors>
4: <endpointBehaviors>
5: <behavior name="webHttp">
6: <webHttp automaticFormatSelectionEnabled="true" />
7: </behavior>
8: </endpointBehaviors>
9: </behaviors>
10: <services>
11: <service name="Artech.WcfServices.Service.EmployeesService">
12: <endpoint address="http://127.0.0.1:3721/employees"
13: behaviorConfiguration="webHttp"
14: binding="webHttpBinding"
15: contract="Artech.WcfServices.Service.Interface.IEmployees"/>
16: </service>
17: </services>
18: </system.serviceModel>
19: </configuration>
对于契约接口IEmployees来说,我们通过WebGetAttribute特性用于返回所有员工列表的GetAll操作的回复消息格式设置为Xml。
1: [ServiceContract]
2: public interface IEmployees
3: {
4: //其他成员
5: [WebGet(UriTemplate = "all",ResponseFormat = WebMessageFormat.Xml)]
6: IEnumerable<Employee> GetAll();
7: }
对于REST服务调用来说,其本质就是一种普通的HTTP请求,与针对某个网页的访问并没有什么本质的不同,所以我们完全可以手工生成HTTP请求来进行服务的访问。为此我们创建了如下一个静态方法GetAllEmployees方法通过WebClient对服务的GetAll操作进行调用,并将整个回复消息打印出来,该方法的两个参数分别是作为请求的HTTP消息的Content-Type和Accept报头值。
1: static void GetAllEmployees(string contentType, string accept)
2: {
3: WebClient webClient = new WebClient();
4: if (!string.IsNullOrEmpty(contentType))
5: {
6: webClient.Headers.Add("Content-Type", contentType);
7: }
8:
9: if (!string.IsNullOrEmpty(accept))
10: {
11: webClient.Headers.Add("Accept", accept);
12: }
13: using (StreamReader reader = new StreamReader(webClient.OpenRead(
14: "http://127.0.0.1:3721/employees/all")))
15: {
16: Console.WriteLine(reader.ReadToEnd());
17: }
18: }
然后我们通过调用GetAllEmployees方法进行三次服务调用。第一次调用既没有指定Content-Type报头也没有指定Accept报头,第二次和第三次调用在分别将这两个报头指定为“application/json”。
1: string contentType = "application/json";
2:
3: Console.WriteLine("Content-Type = N/A; Accept = N/A:");
4: GetAllEmployees("", "");
5: Console.WriteLine();
6:
7: Console.WriteLine("Content-Type = application/json; Accept = N/A:");
8: GetAllEmployees(contentType, "");
9: Console.WriteLine();
10:
11: Console.WriteLine("Content-Type = N/A, Accept = application/json:");
12: GetAllEmployees("", contentType);
从如下所示的输出结果我们可以看出:由于服务调用请求没有指定任何媒体类型相关的报头,所以回复消息采用的是契约接口中设置的消息格式Xml。对于后两次服务调用中,由于请求消息中分别通过Content-Type和Accept报头将“期望”的媒体类型设置为application/json,所以Json最终作为回复消息的格式。(S1006)
1: Content-Type = N/A; Accept = N/A:
2: <ArrayOfEmployee xmlns="http://www.artech.com/" xmlns:i="http://www.w3.org/2001/
3: XMLSchema-instance"><Employee><Department>开发部</Department><Grade>G7</Grade><I
4: d>001</Id><Name>张三</Name></Employee><Employee><Department>人事部</Department><
5: Grade>G6</Grade><Id>002</Id><Name>李四</Name></Employee></ArrayOfEmployee>
6:
7: Content-Type = application/json; Accept = N/A:
8: [{"Department":"开发部","Grade":"G7","Id":"001","Name":"张三"},{"Department":"人
9: 事部","Grade":"G6","Id":"002","Name":"李四"}]
10:
11: Content-Type = N/A, Accept = application/json:
12: [{"Department":"开发部","Grade":"G7","Id":"001","Name":"张三"},{"Department":"人
13: 事部","Grade":"G6","Id":"002","Name":"李四"}]
【转】[WCF REST] 帮助页面与自动消息格式(JSON/XML)选择的更多相关文章
- WCF技术剖析之十七:消息(Message)详解(下篇)
原文:WCF技术剖析之十七:消息(Message)详解(下篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]< ...
- WCF技术剖析之十七:消息(Message)详解(中篇)
原文:WCF技术剖析之十七:消息(Message)详解(中篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]在上篇中 ...
- WCF技术剖析之十七:消息(Message)详解(上篇)
原文:WCF技术剖析之十七:消息(Message)详解(上篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]消息交换 ...
- 当滚动条滚动到页面底部自动加载增加内容的js代码
这篇文章主要介绍了如何使用javscript实现滚动条滚动到页面底部自动加载增加页面内容,需要的朋友可以参考下..1,注册页面滚动事件,window.onscroll = function(){ }; ...
- JSP页面实现自动跳转
1 <html><head><script language=javascript> function out(obj) { var i = obj; if ( ...
- JSP页面实现自动跳转!
JSP页面实现自动跳转!一.页面自动刷新: 把如下代码加入<head>区域中<meta http-equiv=”refresh” content=”5″>注:content=” ...
- Android借助Handler,实现ViewPager中页面的自动切换(转)
在很多电商网页及app上都有自动切换的商品的推广快,感觉体验挺不错的,正好今天学习使用ViewPager,因此也实现了一个功能类似的demo. 下面是其中的两个截图: 实现一个自动 ...
- Js 在页面中输入消息的几种方式
一.方式 alert(“”); confirm(“”) ; prompt(“”); 接收用户信息 console.log(“”); 在网页控制台中输出消息 document. ...
- 解决Intellij Idea下修改jsp页面不自动更新
解决Intellij Idea下修改jsp页面不自动更新 On frame deactivation:被设置成了Do nothing 解决办法:改为Update resources(更新资源)或者Up ...
随机推荐
- asp.net mvc+web api+easyui
前奏:第一次写博客,记录一下学习和开发的过程. 现在写的是一个后台管理系统,有基本的权限功能,其他功能都可以扩展.用到的技术是 asp.net mvc5,web api 2,entityframewo ...
- Hadoop_Block的几种状态_DataNode
在Hadoop 2.0 中HDFS 引入了 append 和 hflush 功能之后, 需要为 数据块增加新的状态 来尽最大可能的保证数据的一致性. 参阅文档: http://files.cnblog ...
- 还原data block dumps实际值
前天看了一个案例因为丢了表上的数据,从索引block中找回了值 转储了oracle block的值,如何得到它真正表中的值,也算 是dump(val,16)的逆运算 sys@ORCL>conn ...
- iOS中打印系统详细日志
Q:如何打印当前的函数和行号? A:我们可以在打印时使用一些预编译宏作为打印参数,来打印当前的函数和行号.如: 1 NSLog(@"%s:%d obj=%@", __func__, ...
- ASP.NET配置KindEditor文本编辑器-图文实例
1.什么是KindEditor KindEditor 是一套开源的在线HTML编辑器,主要用于让用户在网站上获得所见即所得编辑效果,开发人员可以用 KindEditor 把传统的多行文本输入框(tex ...
- linear model for classification
不同error function比较
- PHP程序开发人员要掌握的知识
文件目录处理函数包80%以上的函数的功能的灵活运用. 日期时间函数中的80%以上的函数的功能的灵活运用 数学函数库中的100%的内容. 网络库中的60%以上的内容,对各个函数的功能比较熟悉. 字符串处 ...
- thinksns解析1
1.数据库 这儿是关于数据库的封装,还是挺厉害的,最终select中完成sql语句的封装,最后由query来完成底层api 2.初始化过程 sns也是通过框架完成显示调用,一开始通过i ...
- Mac OS X 好用的软件包管理工具 Homebrew
github地址:https://github.com/Homebrew/homebrew 安装方法:http://brew.sh/
- pushState与replaceState区别
history.pushState(state, title, url) 将当前URL和history.state加入到history中,并用新的state和URL替换当前.不会造成页面刷新. sta ...