Rest 它是用于创建分布式超文本媒体的一种架构方式,我们可以通过标准的HTTP(GET,POST,PUT,DELETE)操作来构建基于面向资源的软件架构方式(Resource-Oriented Architecture (ROA))。它是独立于任何技术或者平台的,所以人们经常将符合这种操作规范的服务称为“RESTful services”。因为WCF能够构建符合这种规范的服务,所以我们经常称之为 WCF Restful Services。
由于传统的WCF Service可以使用tcp,net.msmq,http等协议进行数据交换,并且采用了RPC(Remote Procedure Call)的工作方式,客户端需要添加对服务端的引用才能完成。但是WCF Restful Service完全使用Http协议来进行,并且无需添加客户端引用,所以方便很多。
WebInvoke
其中,Method 方法主要是表明可以接受客户端的请求类型,这里有四种:GET,POST,PUT,DELETE,其中GET为请求数据,POST为更新数据,PUT为新增数据,DELETE代表着删除数据。
然后ResponseFormat 则代表着返回的数据组织,如果是Json则表明客户端会接收到Json数据,如果是XML则表明客户端会接收到XML组织的数据。BodyStyle 代表返回数据的包装对象,如果是Bare则表明数据无任何包装,原生数据返回;如果是Wrapped则表明数据会在最外层包装一个当前函数名称加上Result的套。比如对于Delete对象,则会返回 DeleteResult:{******},会造成DataContractJsonSerializer无法进行反序列化。
UriTemplate 主要用于指定操作的URI路径,只要用户输入了合法路径并采用了正确的请求方式,就会触发该函数。
最后说到的就是URI后面跟的参数的问题,由于函数只能接受string类型的,所以如果传入参数是string类型,则可以使用UriTemplate = "{bookID}"的路径,反之,则需要加上/?param1={paramname}的方式
服务端
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Runtime.Serialization; 5 using System.ServiceModel; 6 using System.ServiceModel.Web; 7 using System.Text; 8 9 namespace IISWCF 10 { 11 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。 12 [ServiceContract] 13 public interface IService1 14 { 15 16 #region TEST 17 18 [OperationContract(Name = "TestPost")] 19 [WebInvoke(Method = "POST", UriTemplate = "TestPost/{str}", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] 20 UserInfo TestPost(string str); 21 22 [OperationContract, WebInvoke(Method = "GET", UriTemplate = "TestGet1")] 23 string TestGet1(); 24 25 [OperationContract(Name = "TestGet2")] 26 [WebGet(UriTemplate = "TestGet2/{Code}/{Card}", 27 BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Xml)] 28 UserInfo TestGet2(string Code, string Card); 29 30 #endregion 31 } 32 33 34 // 使用下面示例中说明的数据约定将复合类型添加到服务操作。 35 [DataContract] 36 public class UserInfo 37 { 38 [DataMember] 39 public string Name { get; set; } 40 [DataMember] 41 public string Code { get; set; } 42 [DataMember] 43 public string Card { get; set; } 44 } 45 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Runtime.Serialization; 5 using System.ServiceModel; 6 using System.ServiceModel.Web; 7 using System.Text; 8 9 namespace IISWCF 10 { 11 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。 12 // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。 13 public class Service1 : IService1 14 { 15 #region TEST 16 17 public UserInfo TestPost(string str) 18 { 19 UserInfo u = new UserInfo(); 20 u.Name = str; 21 return u; 22 } 23 24 public string TestGet1() 25 { 26 return "调用成功!"; 27 } 28 29 public UserInfo TestGet2(string Code, string Card) 30 { 31 UserInfo u = new UserInfo(); 32 u.Code = Code; 33 u.Card = Card; 34 return u; 35 } 36 37 #endregion 38 39 } 40 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <system.web> 4 <compilation debug="true" targetFramework="4.0" /> 5 </system.web> 6 <system.serviceModel> 7 <services> 8 <service behaviorConfiguration="GetPostBehavior" name="IISWCF.Service1"> 9 <endpoint address="" behaviorConfiguration="GetPostEndBehaviors" binding="webHttpBinding" 10 contract="IISWCF.IService1"> 11 </endpoint> 12 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 13 </service> 14 </services> 15 <behaviors> 16 <endpointBehaviors> 17 <behavior name="GetPostEndBehaviors"> 18 <webHttp /> 19 </behavior> 20 </endpointBehaviors> 21 <serviceBehaviors> 22 <behavior name="GetPostBehavior"> 23 <serviceMetadata httpGetEnabled="true" /> 24 <serviceDebug includeExceptionDetailInFaults="false" /> 25 </behavior> 26 </serviceBehaviors> 27 </behaviors> 28 <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 29 </system.serviceModel> 30 <system.webServer> 31 <modules runAllManagedModulesForAllRequests="true"/> 32 <!-- 33 若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。 34 在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。 35 --> 36 <directoryBrowse enabled="true"/> 37 </system.webServer> 38 39 </configuration>
客户端代码
1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.Linq; 5 using System.Net; 6 using System.Text; 7 8 namespace ClientPost 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 var url = "http://localhost:6729/Service1.svc"; 15 try 16 { 17 Console.WriteLine("Post Method TestPost"); 18 string parms = "张三"; 19 string method = "TestPost"; 20 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url + "/" + method + "/" + parms); 21 request.Method = "POST"; 22 request.ContentType = "text/plain"; 23 Stream requestStram = request.GetRequestStream(); 24 requestStram.Close(); 25 HttpWebResponse myResponse = (HttpWebResponse)request.GetResponse(); 26 StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8); 27 string ReqResult = reader.ReadToEnd(); 28 Console.WriteLine(ReqResult); 29 Console.WriteLine(); 30 } 31 catch (Exception ex) 32 { 33 Console.WriteLine(ex.ToString()); 34 } 35 36 try 37 { 38 Console.WriteLine("Get Method TestGet1"); 39 HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url + "/TestGet1"); 40 httpWebRequest.ContentType = "application/json"; 41 httpWebRequest.Method = "GET"; 42 httpWebRequest.Timeout = 20000; 43 HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 44 StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()); 45 string responseContent = streamReader.ReadToEnd(); 46 httpWebResponse.Close(); 47 streamReader.Close(); 48 Console.WriteLine(responseContent); 49 Console.WriteLine(); 50 } 51 catch (Exception ex) 52 { 53 Console.WriteLine(ex.ToString()); 54 } 55 56 try 57 { 58 Console.WriteLine("Get Method TestGet2"); 59 HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url + "/TestGet2/code123/card456"); 60 httpWebRequest.ContentType = "application/json"; 61 httpWebRequest.Method = "GET"; 62 httpWebRequest.Timeout = 20000; 63 HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 64 StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()); 65 string responseContent = streamReader.ReadToEnd(); 66 httpWebResponse.Close(); 67 streamReader.Close(); 68 Console.WriteLine(responseContent); 69 } 70 catch (Exception ex) 71 { 72 Console.WriteLine(ex.ToString()); 73 } 74 Console.ReadLine(); 75 } 76 } 77 }
运行结果:
源码下载WCF-Post-Get.rar