[转]十五天精通WCF——第十三天 用WCF来玩Rest
在我们玩wcf的时候,都会潜意识的觉得wcf就是通过soap协议交换消息的,并且可以在basic,tcp,msmq等等绑定中任意切换,
牛逼的一塌糊涂,但是呢,如果说哪一天wcf不再使用soap协议,而是采用json格式的字符串,是不是有一点颠覆你对wcf的认识的???
从传统意义上说,wcf是非常重量级的,很明白的一个例子就是太多太多的配置,尤其是Behavior的配置,而且behavior对wcf来说又是重
中之重,它对wcf的扩展和性能又是最重要的,可恨的是wcf在binding,behavior,contract之中的配置又是非常非常的保守,可以说用
wcf来玩分布式,这些默认配置是完全做不到的,就比如说basicbinding的基类HttpBindingBase。

抱怨的话我也不说了,可能微软也觉得这个问题是个不小的问题,然后就有了轻量级的 asp.net web api,你可以看到它和wcf比起来精
简多了,也许让我们这些码农更加的专注于业务吧,既然wcf带了这玩意,我也得必须约谈一下。
一:UriTemplate
要说rest,还得先说UriTemplate,因为wcf用UriTemplate来做rest中的uri模板匹配,然后用WebInvoke这个OperationBehavior
插入到wcf的心脏中,说的玄乎一点,这个就有点像mvc中的路由匹配机制,下面我举个例子:
1. 用UriTemplate来告知可以监视的完整Url
从下面的图中,可以看到三个元素:服务地址,模板,入参(这里面的”1“),这三个元素组合在一起,就构成了完整的remote url,
然后这个完整的url就是我模板(/User/{id})监视的对象。

2. 通过UriTemplate来解析url中的参数。
既然可以构建url,那当然可以解析url啦,对吧,下面这张图可以很清晰的告知你,当外来的url=http://127.0.1:1920/HomeService
/User/1过来的时候应该被哪个uriTemplate所接收。

正是因为UriTemplate具有这样的url构建和解析能力,所以wcf就把UriTemplate作为WebInvoke和WebGet这两个属性的参数来动态
解析外来的url,然后根据这个url分配到具体的服务方法上,下面我们具体看一看。
二:WebGet,WebInvoke的使用
刚才也说了,WebGet和WebInvoke正是用了UriTemplate,才具有了路由转向的功能,还有就是默认返回的是xml,这里就用json
值作为服务返回的格式

[ServiceContract]
public interface IHomeService
{
[OperationContract]
[WebGet(UriTemplate = "Get/{id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
Student Get(string id); [OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "Add", RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
string Add(Student stu);
}

对了,Rest推荐使用Http协议中的Get,Post,Delete,Put来作为CURD的状态机制,然后就是你如果看懂了UriTemplate,那你现在应
该知道这个Template在监视什么类型的url。做完了上面的coding,下面我们需要在webconfig中通过behavior来指定启动“web编程模型”,
就比如下面这样。

<?xml version="1.0" encoding="utf-8"?>
<configuration> <system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="ActivityTracing">
<listeners>
<add name="mylisteners" type="System.Diagnostics.XmlWriterTraceListener" initializeData="E:\1.txt" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="ActivityTracing">
<listeners>
<add name="messagelogging" type="System.Diagnostics.XmlWriterTraceListener" initializeData="E:\2.txt"/>
</listeners>
</source>
</sources>
<trace autoflush="true"/>
</system.diagnostics> <system.serviceModel> <diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtTransportLevel="true" />
</diagnostics> <behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
33 <endpointBehaviors>
34 <behavior name="webbehavior">
35 <webHttp />
36 </behavior>
37 </endpointBehaviors>
</behaviors> <services>
<service name="MyService.HomeService">
<endpoint address="HomeService" binding="webHttpBinding" behaviorConfiguration="webbehavior"
contract="MyService.IHomeService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://127.0.0.1:1920" />
</baseAddresses>
</host>
</service>
</services> </system.serviceModel> </configuration>

其实呢?也就是代码中的WebHttpBehavior类

好了,我现在服务地址也出来了:http://127.0.0.1:1920 ,然后服务方法的template也指定了。只要http.sys监控到了template
匹配的url,服务方法就会被执行,比如我现在在浏览器里面输入:http://127.0.0.1:1920/HomeService/Get/1 来测试下Get操作。

可以看到,get方法成功了,也正确的匹配了我的服务方法Get。

public class HomeService : IHomeService
{
public Student Get(string id)
{
return new Student() { ID = Convert.ToInt32(id), Name = "hxc", SNS = "" };
} public string Add(Student stu)
{
return "hello";
}
}

然后我们看看Add方法,我在HttpWebRequest中模拟测试如下。
class Program
{
static void Main(string[] args)
{
Run();
} /// <summary>
/// 报告系统错误
/// </summary>
/// <param name="ex"></param>
/// <returns></returns>
public static void Run()
{
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create("http://127.0.0.1:1920/HomeService/Add");
Encoding encoding = Encoding.UTF8; string param = new JavaScriptSerializer().Serialize(new { ID = "", Name = "hxc", SNS = "" });
byte[] bs = Encoding.ASCII.GetBytes(param); string responseData = String.Empty;
req.Method = "POST";
req.ContentType = "application/json";
req.ContentLength = bs.Length;
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(bs, , bs.Length);
reqStream.Close();
}
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
{
using (StreamReader reader = new StreamReader(response.GetResponseStream(), encoding))
{
responseData = reader.ReadToEnd().ToString();
}
}
}
}

好了,大概就说这么多了,如果说你不嫌麻烦,你可以用WCF Rest,还有就是不要忘了很多的默认配置,如果你觉得太繁琐,
可以用用asp.net web api。

[转]十五天精通WCF——第十三天 用WCF来玩Rest的更多相关文章
- 十五天精通WCF——第十三天 用WCF来玩Rest
在我们玩wcf的时候,都会潜意识的觉得wcf就是通过soap协议交换消息的,并且可以在basic,tcp,msmq等等绑定中任意切换, 牛逼的一塌糊涂,但是呢,如果说哪一天wcf不再使用soap协议, ...
- 十五天精通WCF——第一天 三种Binding让你KO80%的业务
转眼wcf技术已经出现很多年了,也在.net界混的风生水起,同时.net也是一个高度封装的框架,作为在wcf食物链最顶端的我们所能做的任务已经简单的不能再简单了, 再简单的话马路上的大妈也能写wcf了 ...
- 十五天精通WCF——第十四天 一起聊聊FaultException
我们在玩web编程的时候,可能你会不经意的见到一些http500的错误,我想你应该不会陌生的,原因你应该也知道,服务器异常嘛, 这时候clr会把这个未处理的异常抛给iis并且包装成http500的错 ...
- [转]十五天精通WCF——第十四天 一起聊聊FaultException
我们在玩web编程的时候,可能你会不经意的见到一些http500的错误,我想你应该不会陌生的,原因你应该也知道,服务器异常嘛, 这时候clr会把这个未处理的异常抛给iis并且包装成http500的错 ...
- [转]十五天精通WCF——第一天 三种Binding让你KO80%的业务
转眼wcf技术已经出现很多年了,也在.net界混的风生水起,同时.net也是一个高度封装的框架,作为在wcf食物链最顶端的我们所能做的任务已经简单的不能再简单了, 再简单的话马路上的大妈也能写wcf了 ...
- 十五天精通WCF——终结篇 那些你需要注意的坑
终于一路走来,到了本系列的最后一篇了,这一篇也没什么好说的,整体知识框架已经在前面的系列文章中讲完了,wcf的配置众多,如果 不加一些指定配置,你可能会遇到一些灾难性的后果,快来一睹为快吧. 一: 第 ...
- 十五天精通WCF——第十二天 说说wcf中的那几种序列化
我们都知道wcf是由信道栈组成的,在我们传输的参数走到传输信道层之前,先需要经过序列化的过程,也就是将参数序列化为message,这篇 我们就来说说这里的序列化,蛮有意思的,可能初学者也明白,在wcf ...
- 十五天精通WCF——第十一天 如何对wcf进行全程监控
说点题外话,我们在玩asp.net的时候,都知道有一个叼毛玩意叫做“生命周期”,我们可以用httpmodule在先于页面的page_load中 做一些拦截,这样做的好处有很多,比如记录日志,参数过滤, ...
- 十五天精通WCF——第十天 学会用SvcConfigEditor来简化配置
我们在玩wcf项目的时候,都是自己手工编写system.serviceModel下面的配置,虽然在webconfig中做wcf的服务配置的时候,vs提供大多 数的代码提示,但对于不太熟悉服务配置的小鸟 ...
随机推荐
- 个人微信二次开发API接口
通过这个API接口可以做什么? 通过我们提供的API接口您可以开发: 工作手机(如:X创,X码,XX管家等) 微信群讲课软件(如:讲课X师,一起X堂等) 微信社群管理软件(如:小X管家,微X助手等) ...
- mahjong
题目描述 “为什么, 你们的力量在哪里得到如此地......”“我们比 1 分钟前的我们还要进步, 虽然很微小, 但每转一圈就会前进一寸.这就是钻头啊!”“那才是通向毁灭的道路.为什么就没有意识到螺旋 ...
- 题解报告:poj 3233 Matrix Power Series(矩阵快速幂)
题目链接:http://poj.org/problem?id=3233 Description Given a n × n matrix A and a positive integer k, fin ...
- Python 必选参数,默认参数,可变参数,关键字参数和命名关键字参数
Py的参数还真是多,用起来还是很方便的,这么多参数种类可见它在工程上的实用性还是非常广泛的. 挺有意思的,本文主要参照Liaoxuefeng的Python教程. #必选参数 def quadratic ...
- 322 Coin Change 零钱兑换
给定不同面额的硬币(coins)和一个总金额(amount).写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合方式能组成总金额,返回-1.示例 1:coins = [1, ...
- [转]Android自定义Adapter的ListView的思路及代码
本文转自:http://www.jb51.net/article/37236.htm 在开发中,我们经常使用到ListView这个控件.Android的API也提供了许多创建ListView适配器的快 ...
- JavaScript 封装插件学习笔记(一)
此篇只是笔记,在借鉴.参考.模仿的过程,可能不完整,请多指教! 定义插件名称要注意命名冲突,防止全局污染. 1.第一种Javascript对象命名:(Javascript语言是“先解析,后运行”,解析 ...
- asp.net——统计输入的字符数目
asp.net——统计输入的字符数目 题目: 在页面中有一个TextBox输入框,一个显示文字用的Label,一个提交按钮Button.在TextBox中输入一段英文字母,点击按钮提交后统计其中字母‘ ...
- 13、scala模式匹配
1.模式匹配的基础语法 2.对类型进行模式匹配 3.对Array和List的元素进行模式匹配 4.case class与模式匹配 5.Option与模式匹配 1.模式匹配的基础语法 Scala提供了m ...
- 【VHDL】深度讲解二进制无符号和有符号加法处理溢出的问题
1.Unsigned adders 这个比较简单,只需在A.B前面扩展一位0防止溢出,溢出的数填到第n位cout,n-1到0位就是sum. , 2.Signed adders 一开始也搞不懂下图中为什 ...