wcf 服务创建,配置,测试
一.WCF创建:
常规的创建WCF服务是通过SOAP传输的,很多网站开发人员想放弃使用XML而使用JSON,这个时候可以参照:http://www.cnblogs.com/zhili/p/WCFRestService.html?utm_source=tuicool&utm_medium=referral
WCF 3.5中对Rest服务做了支持。WCF在System.ServiceModel.Web组件中新增了ResT编程,Rest编程有两个主要的新属性: WebGetAttribute 和 WebInvokeAttribute ,还有一个URI模板机制,帮助你声明每种方法响应使用的URI和动词。.NET Framework还提供了一个新的绑定(WebHttpBinding)和新的行为(WebHttpBehavior),此外,还提供了WebServiceHost和WebServiceHostFactory类来对Rest服务进行支持。
以前我们都是把WCF服务抽象为操作的概念,而Rest最早是由Roy Thomas Fielding 在他的博士论文( “体系结构风格和基于网络软件体系的设计 ”)中提出的。Rest服务是将服务抽象为资源,每个资源都有一个唯一的统一资源标识符(URI),我们不再是通过调用操作的方式与服务进行交互了,而是通过HTTP标准动词(GET、POST、PUT和DELETE)的统一接口来完成。总之一句话概括,Rest服务换了一种思维方式,把服务也当成一种资源,通过Get、Post、Put和Delete这些HTTP动词来进行交互。这样,问题就来了,Rest服务具有什么好处呢?即我们为什么要去关注Rest和实现它呢?
Rest优势就在于其使用极其简单,Rest服务要求很少的编码工作量,可以减少很多不必要的工作。Rest服务主要有以下优点:
- 无需引入SOAP消息传输层,轻量级和高效率的HTTP格式可直接被应用。
- 可以轻易地在任何编程语言中实现,尤其是在JS中。使用SOAP的服务与JS交互非常繁琐,而使用Rest服务与JS交互非常简单。
- 可以不使用任何编程语言就能访问服务,而只需要使用Web浏览器即可。
- 更好的性能和缓存支持。使用Rest服务可以改善响应时间和改善用户体验。
- 可扩展性和无状态性。Rest服务基于HTTP协议,每个请求都是独立的,一旦被调用,服务器不保留任何会话,这样可以更具响应性,通过减少通讯状态的维护工作来提供服务的可扩展性。
Rest和SOAP比较:
REST目前只基于HTTP和HTTPS协议,而SOAP可支持任何传输协议,包括HTTP/HTTPS、TCP、SMTP等协议。另外Rest服务除了能使用XML作为数据承载外,还有JSON,RSS和 ATOM 形式。
Rest与SOAP对应的比较如下所示:
- SOAP是一种工业标准,面对的应用需求时RPC(远程过程调用),而Rest面对的应用需求是分布式Web系统。
- Rest服务强调数据,请求和响应消息都是数据的封装,而SOAP服务更强调接口,SOAP消息封装的是过程调用。Rest是面向资源的,而SOAP是面向接口的。
- Rest架构下,HTTP是承载协议,也是应用协议,而SOAP架构下,HTTP只是承载协议,SOAP才是应用协议。
那在什么情况下使用Rest,什么情况下使用SOAP呢?这要看具体的实际情况。具体应用场景如下所示:
- 远程调用用SOAP。如果服务是作为一种功能提供,客户端调用服务是为了执行一个功能,用SOAP,比如常见的需求是认证授权。而数据服务用Rest。
- 要更多的考虑非功能需求时使用SOAP,如需考虑安全、传输和协议等需求的情况下。
- 低带宽、客户端的处理能力受限的场合可以考虑使用Rest。如在PDA或手机上消费服务。
第一步:创建Rest服务接口和实现。
[ServiceContract(Namespace ="http://www.cnblogs.com/zhili/")]//也可以不加直接通过服务url作为地址
public interface IEmployees
{
// 契约操作不再使用操作契约的方式来标识,而是使用WebGetAttribute特性来标识,从而表明该服务是Rest服务
//[OperationContract]//Rest可以不适用OperactionContract标识
[WebGet(UriTemplate = "all")]
//[WebGet(UriTemplate = "all", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
IEnumerable<Employee> GetAll(); [WebGet(UriTemplate = "{id}")]
////[WebGet(UriTemplate = "MySplit/{id}", Method = "POST" ,ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
Employee Get(string id); [WebInvoke(UriTemplate="/", Method="PUT")]
void Create(Employee employee); [WebInvoke(UriTemplate = "/", Method = "POST")]
void Update(Employee employee); [WebInvoke(UriTemplate = "/", Method = "DELETE")]
void Delete(string id);
}
//[Serializable],如果不是使用SOAP协议,可以不加
[DataContract(Namespace = "http://www.cnblogs.com.zhili/")]
public class Employee
{
//注意:对外访问的数据属性必须保证其get和set都是public,不然,数据传输不了的
[DataMember]
public string Id { get; set; } [DataMember]
public string Name { get; set; } [DataMember]
public string Department { get; set; }
}
从上面代码可以看出,Rest服务不再使用OperactionContract的方式来标识操作了,此时在Rest架构下,每个操作都被当做一种资源对待,所以这里的操作使用了WebGetAttribute特性和WebInvokeAttribute来标识。下面具体看看契约的具体实现,即Rest服务的实现代码。实现服务的代码就不加了。
第二步:实现Rest服务宿主。这里还是使用控制台程序来作为宿主程序
namespace RestServiceHost
{
class Program
{
static void Main(string[] args)
{
// Rest服务使用WebServiceHost类来为服务提供宿主
using (WebServiceHost webHost = new WebServiceHost(typeof(EmployeesService)))
{
webHost.Opened += delegate
{
Console.WriteLine("Rest Employee Service 开启成功!");
}; webHost.Open();
Console.Read();
}
}
}
}
对应的配置文件内容如下所示:
<configuration>
<system.serviceModel>
<services>
<service name="WCFContractAndService.EmployeesService">
<!--这里Rest服务只能使用WebHttpBinding来作为绑定-->
<endpoint address="http://localhost:9003/employeeService"
binding="webHttpBinding" contract="RestContract.IEmployees"/>
</service>
</services>
</system.serviceModel>
</configuration>
第三步:实现Rest服务调用客户端。这里通过通道工厂的方式来创建代理对象的
namespace WCFClient
{
class Program
{
static void Main(string[] args)
{
using (ChannelFactory<IEmployees> channelFactory = new ChannelFactory<IEmployees>("employeeService"))
{
// 创建代理类
IEmployees proxy = channelFactory.CreateChannel(); Console.WriteLine("所有员工信息:"); // 通过代理类来对Rest服务进行操作
Array.ForEach<Employee>(proxy.GetAll().ToArray(), emp => Console.WriteLine(emp.ToString())); Console.WriteLine("\n添加一个新员工{0003}:");
proxy.Create(new Employee
{
Id = "", Name="李四", Department="财务部"
}); Array.ForEach<Employee>(proxy.GetAll().ToArray(), emp => Console.WriteLine(emp.ToString())); Console.WriteLine("\n修改员工(0003)信息:");
proxy.Update(new Employee
{
Id = "", Name="李四", Department = "销售部"
});
Array.ForEach<Employee>(proxy.GetAll().ToArray(), emp => Console.WriteLine(emp.ToString()));
Console.WriteLine("\n删除员工(0002)信息:");
proxy.Delete("");
Array.ForEach<Employee>(proxy.GetAll().ToArray(), emp => Console.WriteLine(emp.ToString())); Console.Read();
}
}
}
}
客户端对应的配置文件内容如下所示:
<configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint name="employeeService" address="http://localhost:9003/employeeService" binding="webHttpBinding" behaviorConfiguration="webBehavior" contract="RestContract.IEmployees"> </endpoint>
</client>
</system.serviceModel>
</configuration>
二.WCF配置文件
配置也是WCF编程中的主要组成部分。在以往的.net应用程序中,我们会把DBConn和一些动态加载类及变量写在配置文件里。但WCF有所不同。他指定向客户端公开的服务,包括服务的地址、服务用于发送和接收消息的传输和消息编码,以及服务需要的安全类型等。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel> <!--配置服务和终结点开始-->
<services>
<service>
<endpoint></endpoint>
</service>
</services>
<!--配置服务和终结点结束--> <!--配置绑定开始-->
<bindings>
<netTcpBinding>
<binding>
</binding>
</netTcpBinding>
</bindings>
<!--配置绑定结束--> <!--配置行为开始-->
<behaviors>
<!--endpointBehaviors在Rest时候用,也可以不配置,可以加入一些自定义的,自由发挥-->
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
</behavior>
</serviceBehaviors>
</behaviors>
<!--配置行为结束--> </system.serviceModel>
</configuration>
Service配置节[必须有]:配置服务、接口和终结点。每个Service都会有以下两个属性。name:名称空间.类名[服务的具体实现类]。behaviorConfiguration:一个在behaviors节点中找到的名称。
Binding配置节[可有可无]:配置绑定,如http,tcp等。
Behavior配置节[可有可无]:配置行为,如认证等。
//附一个各种自定义配置的,英文基本代表了各个意思
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding0" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
三.WCF测试:
调试:将Web.config中的 <webHttp /> 修改为 <webHttp helpEnabled="true" />,将可以在浏览器页面中列举出可用接口,并提供提交的数据样例。打开IE浏览器,在地址栏输入:http://localhost:3000/MyService.svc/help 即可。
1) 使用微软VisualStuio的wcf测试客户端(\Common7\IDE\WcfTestClient.exe):
双击接口方法名,输入参数,测试。
2) 借用chrome扩展工具PostMan测试(Rest方式,也可以直接在地址栏输入地址)
wcf 服务创建,配置,测试的更多相关文章
- WCF服务创建与使用(双工模式)
昨天发布了<WCF服务创建与使用(请求应答模式)>,今天继续学习与强化在双工模式下WCF服务创建与使用,步骤与代码如下. 第一步,定义服务契约(Service Contract),注意Se ...
- 携程框架Apollo实现.NET Core微服务统一配置(测试环境-单机)
Apollo实现.NET Core微服务统一配置(测试环境-单机) https://www.cnblogs.com/guolianyu/p/10065999.html 一.前言 注:此篇只是为测试环境 ...
- WCF服务创建到发布(SqlServer版)
在本示例开始之前,让我们先来了解一下什么是wcf? wcf有哪些特点? wcf是一个面向服务编程的综合分层架构.该架构的项层为服务模型层. 使用户用最少的时间和精力建立自己的软件产品和外界通信的模型. ...
- WCF服务创建与使用(请求应答模式)
不说废话,直接上代码.以下服务创建是在独立的WCF类库中,若采用WCF应程程序,定义及创建服务代码均相同,但文件名不同,是CalculatorService.svc 第一步,定义服务契约(Servic ...
- 基于Apollo实现.NET Core微服务统一配置(测试环境-单机)
一.前言 注:此篇只是为测试环境下的快速入门.后续会给大家带来生产环境下得实战开发. 具体的大家可以去看官方推荐.非常的简单明了.以下介绍引用官方内容: Apollo(阿波罗)是携程框架部门研发的分布 ...
- WCF服务创建与抛出强类型SOAP Fault
原创地址:http://www.cnblogs.com/jfzhu/p/4060666.html 转载请注明出处 前面的文章<WCF服务的异常消息>中介绍过,如果WCF Service发生 ...
- 编写WCF服务时右击配置文件无“Edit WCF Configuration”(编辑 WCF 配置)远程的解决办法
原文:编写WCF服务时右击配置文件无“Edit WCF Configuration”远程的解决办法 今天在看<WCF揭秘>书中看到作者提出可以在一个WCF Host应用程序的App.Con ...
- WCF入门(五)---创建WCF服务
使用Microsoft Visual Studio2012创建WCF服务,理解如下所有必要的编码,更好地创建WCF服务的概念,这里做一个简单的任务. 启动Visual Studio 2012. 单击新 ...
- 记录:Web无引用无配置方式动态调用WCF服务
这几年一直用WebApi较多,最近项目中有个需求比较适合使用WCF,以前也用过JQuery直接调用Wcf的,但是说实话真的忘了… 所以这次解决完还是花几分钟记录一下 WCF服务端:宿主在现有Win服务 ...
随机推荐
- c# CLR无法从 COM 上下文 0x51cd20 转换为 COM 上下文 0x51ce90
调试菜单--->异常---->managed debugging assistants栏下ContextSwitchDeadlock 前面的√去掉
- ZigBee设备入网流程之关联方式
ZigBee设备入网流程 ZigBee设备入网有关联方式和直接方式两种,我所熟悉的是关联方式,这也是最常用的方式. 关联方式 step1 设备发出Beacon Request 设备会在预先设置的几个信 ...
- matlab的二维卷积操作(转)
MATLAB的conv2函数实现步骤(conv2(A,B)): 其中,矩阵A和B的尺寸分别为ma*na即mb*nb ① 对矩阵A补零,第一行之前和最后一行之后都补mb-1行,第一列之前和最后一列之后都 ...
- 【Linux】- 不可不知的小技巧
1.Tab键:输入文件或目录名的前几个字符,然后按TAB键,如无相重的,完整的文件名立即自动在命令行出现:如有相重的,再按一下TAB键,系统会列出当前目录下所有以这几个字符开头的名字. 在命令行下,只 ...
- React 16.x & Hooks
React 16.x & Hooks Hooks https://reactjs.org/docs/hooks-intro.html https://reactjs.org/docs/hook ...
- delphi 取得数据集某字段值的六种方法
//取name字段的示例 edit1.Text:=ADOquery1.Fields[2].AsString; //取得数据表的第二个字段的值 edit2.Text:=ADOquery1.Fie ...
- OpenCV2.3.1在Win7+VS2010下的配置过程
1. 假定电脑上已经安装了VS2010程序,若没有,首先安装vs2010.下载OpenCV2.3.1,网址:http://sourceforge.net/projects/opencvlibrary ...
- 【刷题】BZOJ 3513 [MUTC2013]idiots
Description 给定n个长度分别为a_i的木棒,问随机选择3个木棒能够拼成三角形的概率. Input 第一行T(T<=100),表示数据组数. 接下来若干行描述T组数据,每组数据第一行是 ...
- [LOJ2540] [PKUWC2018] 随机算法
题目链接 LOJ:https://loj.ac/problem/2540 Solution 写的时候脑子不太清醒码了好长然后时间\(LOJ\)垫底... 反正随便状压\(dp\)一下就好了,设\(f[ ...
- 洛谷 P2757 [国家集训队]等差子序列 解题报告
P2757 [国家集训队]等差子序列 题目描述 给一个\(1\)到\(N\)的排列\(\{A_i\}\),询问是否存在 \[1 \le p_1<p_2<p_3<p_4<p_5& ...