Web服务类别有两种,一种是基于SOAP协议的服务,另一种是基于HTTP协议的REST架构风格的服务。REST服务的数据格式有两种:XML 和 JSON,REST服务已被大量应用于移动互联网中。
本文将简要介绍创建一个REST服务应用程序以及使用它(仅仅是个示例,没有做代码优化)。
一、创建REST服务
1.新建一个空的解决方案,添加“WCF服务应用程序”
2.添加一个服务契约接口:IStudentService.cs,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ServiceModel; using System.Runtime.Serialization; namespace RESTService { /// <summary> /// 服务契约:对学生信息进行增删改查 /// </summary> [ServiceContract] public interface IStudentService { [OperationContract] string GetStuName(string id); [OperationContract] Student GetStu(string id); [OperationContract] bool UpdateStuAge(Student stu); [OperationContract] bool AddStu(Student stu); [OperationContract] bool DeleteStu(Student stu); } /// <summary> /// 数据契约 /// </summary> [DataContract] public class Student { [DataMember] public string ID { get; set; } [DataMember] public string Name { get; set; } [DataMember] public int Age { get; set; } } }
3.添加REST服务:StudentService.svc,如图:
该服务类实现上述服务契约接口,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Activation; using System.ServiceModel.Web; using System.Text; namespace RESTService { [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class StudentService : IStudentService { // 要使用 HTTP GET,请添加 [WebGet] 特性。(默认 ResponseFormat 为 WebMessageFormat.Json) // 要创建返回 XML 的操作, // 请添加 [WebGet(ResponseFormat=WebMessageFormat.Xml)], // 并在操作正文中包括以下行: // WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml"; private static List<Student> _listStu; public StudentService() { _listStu = new List<Student> { new Student{ID="1",Name="Jim",Age=24}, new Student{ID="2",Name="Tom",Age=23} }; } [WebGet(UriTemplate = "REST/GetName/{id}", ResponseFormat = WebMessageFormat.Json)] public string GetStuName(string id) { Student stu = this.GetStu(id); if (stu == null) { return "不存在此学生!"; } else { return stu.Name; } } [WebGet(UriTemplate = "REST/Get/{id}", ResponseFormat = WebMessageFormat.Json)] public Student GetStu(string id) { Student stu = _listStu.Find(s => s.ID == id); return stu; } [WebInvoke(UriTemplate = "REST/Update/", Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] public bool UpdateStuAge(Student stu) { Student stu2 = this.GetStu(stu.ID); if (stu2 == null) { return false; } else { _listStu.Remove(stu2); _listStu.Add(stu); return true; } } [WebInvoke(UriTemplate = "REST/Add/", Method = "PUT", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] public bool AddStu(Student stu) { if (_listStu == null) { _listStu = new List<Student>(); } _listStu.Add(stu); return true; } [WebInvoke(UriTemplate = "REST/Delete/", Method = "DELETE", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] public bool DeleteStu(Student stu) { Student stu2 = this.GetStu(stu.ID); if (stu2 == null) { return false; } else { _listStu.Remove(stu2); return true; } } } }
4.WebConfig文件内容:
<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> </appSettings> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5"/> </system.web> <system.serviceModel> <services> <service name="RESTService.StudentService"> <endpoint address="" behaviorConfiguration="RESTService.StudentServiceAspNetAjaxBehavior" binding="webHttpBinding" contract="RESTService.IStudentService" /> </service> </services> <behaviors> <endpointBehaviors> <behavior name="RESTService.StudentServiceAspNetAjaxBehavior"> <!--<enableWebScript />--> <webHttp helpEnabled="true"/> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> <protocolMapping> <add binding="basicHttpsBinding" scheme="https" /> </protocolMapping> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> <!-- 若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。 在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。 --> <directoryBrowse enabled="true"/> </system.webServer> </configuration>
5.在浏览器中查看REST服务信息
在浏览器地址栏的url后面输入help,即可查看该服务提供了哪些操作
二、调用REST服务
1.为了演示方便,本例采用WinForm应用程序调用REST服务(当然你也可以使用Android,IOS,IPad,WP等等其他客户端进行测试),界面效果如图:
2.后台代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.Serialization.Json; using RESTService; using System.IO; namespace RESTClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// <summary> /// Json 反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="jsonString"></param> /// <returns></returns> public static T JsonDeserialize<T>(string jsonString) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); T obj = (T)serializer.ReadObject(ms); return obj; } /// <summary> /// Json 反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="ms"></param> /// <returns></returns> public static T JsonDeserialize<T>(Stream ms) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); T obj = (T)serializer.ReadObject(ms); return obj; } /// <summary> /// Json 序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="t"></param> /// <returns></returns> public static string JsonSerializer<T>(T t) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); using (MemoryStream ms = new MemoryStream()) { serializer.WriteObject(ms, t); return Encoding.UTF8.GetString(ms.ToArray()); } } /// <summary> /// GET 操作 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnGet_Click(object sender, EventArgs e) { string uri = string.Format("http://localhost:4563/StudentService.svc/rest/get/{0}", this.txtID.Text.Trim()); HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(uri); wr.Method = "GET"; HttpWebResponse resp = (HttpWebResponse)wr.GetResponse(); if (resp.ContentLength <= 0) { MessageBox.Show("不存在此学生!"); this.txtID.Text = ""; this.txtName.Text = ""; this.txtAge.Text = ""; } else { Stream ms = resp.GetResponseStream(); Student stu = JsonDeserialize<Student>(ms); this.txtID.Text = stu.ID; this.txtName.Text = stu.Name; this.txtAge.Text = stu.Age.ToString(); } } /// <summary> /// POST 操作 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnPost_Click(object sender, EventArgs e) { string uri = string.Format("http://localhost:4563/StudentService.svc/rest/update/"); Student stu = new Student(); stu.ID = this.txtID.Text.Trim(); stu.Name = this.txtName.Text.Trim(); stu.Age = Convert.ToInt32(this.txtAge.Text.Trim()); byte[] bs = Encoding.UTF8.GetBytes(JsonSerializer<Student>(stu)); HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(uri); wr.Method = "POST"; wr.ContentLength = bs.Length; wr.ContentType = "application/json"; using (Stream reqStream = wr.GetRequestStream()) { reqStream.Write(bs, 0, bs.Length); } HttpWebResponse resp = (HttpWebResponse)wr.GetResponse(); using (Stream respStream = resp.GetResponseStream()) { StreamReader sr = new StreamReader(respStream); string result = sr.ReadToEnd(); if (result == "true") { MessageBox.Show("更新成功!"); } else { MessageBox.Show("更新失败!"); } } } /// <summary> /// PUT 操作 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnPut_Click(object sender, EventArgs e) { string uri = string.Format("http://localhost:4563/StudentService.svc/rest/add/"); Student stu = new Student(); stu.ID = this.txtID.Text.Trim(); stu.Name = this.txtName.Text.Trim(); stu.Age = Convert.ToInt32(this.txtAge.Text.Trim()); byte[] bs = Encoding.UTF8.GetBytes(JsonSerializer<Student>(stu)); HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(uri); wr.Method = "PUT"; wr.ContentLength = bs.Length; wr.ContentType = "application/json"; using (Stream reqStream = wr.GetRequestStream()) { reqStream.Write(bs, 0, bs.Length); } HttpWebResponse resp = (HttpWebResponse)wr.GetResponse(); using (Stream respStream = resp.GetResponseStream()) { StreamReader sr = new StreamReader(respStream); string result = sr.ReadToEnd(); if (result == "true") { MessageBox.Show("添加成功!"); } else { MessageBox.Show("添加失败!"); } } } /// <summary> /// DELETE 操作 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnDelete_Click(object sender, EventArgs e) { string uri = string.Format("http://localhost:4563/StudentService.svc/rest/delete/"); Student stu = new Student(); stu.ID = this.txtID.Text.Trim(); byte[] bs = Encoding.UTF8.GetBytes(JsonSerializer<Student>(stu)); HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(uri); wr.Method = "DELETE"; wr.ContentLength = bs.Length; wr.ContentType = "application/json"; using (Stream reqStream = wr.GetRequestStream()) { reqStream.Write(bs, 0, bs.Length); } HttpWebResponse resp = (HttpWebResponse)wr.GetResponse(); using (Stream respStream = resp.GetResponseStream()) { StreamReader sr = new StreamReader(respStream); string result = sr.ReadToEnd(); if (result == "true") { MessageBox.Show("删除成功!"); } else { MessageBox.Show("删除失败!"); } } } } }