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="",Name="Jim",Age=},
new Student{ID="",Name="Tom",Age=}
};
} [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;
}
}
}
}

关于WEB消息主体风格的介绍

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 <= )
{
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, , 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, , 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, , 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("删除失败!");
}
}
}
}
}

创建REST服务应用程序的更多相关文章

  1. SharePoint Search之(一):创建Search服务应用程序

    计划写一个关于怎样使用SharePoint Search的系列,包括下面几个方面: (一)创建Search Service Application (二)持续爬网(continues crawl) ( ...

  2. .NET创建一个即是可执行程序又是Windows服务的程序

    不得不说,.NET中安装服务很麻烦,即要创建Service,又要创建ServiceInstall,最后还要弄一堆命令来安装和卸载. 今天给大家提供一种方式,直接使用我们的程序来安装/卸载服务,并且可以 ...

  3. C#/.NET基于Topshelf创建Windows服务的守护程序作为服务启动的客户端桌面程序不显示UI界面的问题分析和解决方案

    本文首发于:码友网--一个专注.NET/.NET Core开发的编程爱好者社区. 文章目录 C#/.NET基于Topshelf创建Windows服务的系列文章目录: C#/.NET基于Topshelf ...

  4. vscode源码分析【四】程序启动的逻辑,最初创建的服务

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...

  5. vs 2010创建Windows服务定时timer程序

    vs 2010创建Windows服务定时timer程序: 版权声明:本文为搜集借鉴各类文章的原创文章,转载请注明出处:  http://www.cnblogs.com/2186009311CFF/p/ ...

  6. C# 创建Windows Service(Windows服务)程序

    本文介绍了如何用C#创建.安装.启动.监控.卸载简单的Windows Service 的内容步骤和注意事项. 一.创建一个Windows Service 1)创建Windows Service项目 2 ...

  7. ASP.NET MVC 5 03 - 安装MVC5并创建第一个应用程序

    不知不觉 又逢年底, 穷的钞票 所剩无几. 朋友圈里 各种装逼, 抹抹眼泪 MVC 继续走起.. 本系列纯属学习笔记,如果哪里有错误或遗漏的地方,希望大家高调指出,当然,我肯定不会低调改正的.(开个小 ...

  8. 用C#创建Windows服务(Windows Services)

    用C#创建Windows服务(Windows Services) 学习:  第一步:创建服务框架 创建一个新的 Windows 服务项目,可以从Visual C# 工程中选取 Windows 服务(W ...

  9. .Net创建windows服务入门

    本文主要记录学习.net 如何创建windows服务. 1.创建一个Windows服务程序 2.新建安装程序 3.修改service文件 代码如下 protected override void On ...

随机推荐

  1. linux启动后自动登录并运行自定义图形界面程序

    在<Ubuntu CTRL+ALT+F1~F6 进入命令模式后不支持中文显示的解决办法>一文中提到linux启动在以后运行一个独占显示器的图形程序的两种办法. 1.不启动xserver,使 ...

  2. (转)Android属性设置android:noHistory="true"

    设置 android:noHistory="true"后,该Activity在statck中不留历史痕迹.默认的值是false. 举例说明,假设有三个Activity分别是:A,B ...

  3. Kafka入门学习(一)

    ====常用开源分布式消息系统 *集群:多台机器组成的系统叫集群. *ActiveMQ还是支持JMS的一种消息中间件. *阿里巴巴metaq,rocketmq都有kafka的影子. *kafka的动态 ...

  4. 03-树2 List Leaves

    二叉树及其遍历 一遍AC,挺开心的hhh~ 简单讲下思路:叶子,顾名思义就是没有左右子树的结点.由于题目要求,叶子结点的输出顺序是从上往下,从左往右.所以用层序遍历法. 当然,这里先找到root树的根 ...

  5. 解决在sublime text3在ubuntu下无法输入中文的问题

    方法链接:https://github.com/lyfeyaj/sublime-text-imfix 效果图:

  6. python-抓取图片

    今天看到博客园一个文章,python抓取图片,也没看内容,心想自己也写一个抓取脚本试试看,一方面自己也在学习python,另一方面毕竟实际工作也经常会遇到这种需要临时写脚本的时候,突击锻炼还是好的嘛. ...

  7. JavaWeb之 JSP:自定义标签

    当jsp的内置标签和jstl标签库内的标签都满足不了需求,这时候就需要开发者自定义标签. 自定义标签 下面我们先来开发一个自定义标签,然后再说它的原理吧! 自定义标签的开发步骤 步骤一 编写一个普通的 ...

  8. 老工程升级到VS2010或以上时会出现 libc.lib 解决方法

    有些网上的工程都比较老,比如用2003之类.一般会有个静态libc.lib.在新版本里已经没有这个库,被微软无情的抛弃. 编译时会出现动态库找不到: 1>LINK : fatal error L ...

  9. chattr 与 lsattr 命令详解

    PS:有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了.chattr命令的作用很大,其中一些功能是由Linux内核版本来支持的,不过现在生产绝大部分跑的li ...

  10. 点击TableView中某行进入下一级界面(Swift)

    TableView这个控件在iOS的开发中非常的常见,他可以较好的展示一个层级结构.这里主要介绍,在点击某个条目的时候,如何进行跳转的下一个界面.以下是官方的关于这个跳转如何去实现,和如何去传递数据的 ...