本章节简单介绍一下使用ASP.NET MVC Web API 做增删改查。目前很多Http服务还是通过REST或者类似RESP的模型来进行数据操作的。下面我们通过创建一个简单的Web API来管理联系人
说明:为了方便数据不使用真正的数据库,而是通过内存数据模拟
1. Web API中包含的方法
Action |
HTTP method |
Relative URI |
GetAllContact |
GET |
/api/contact |
GetContact |
GET |
/api/contact /id |
GetListBySex |
GET |
/api/contact?sex=sex |
PostContact |
POST |
/api/contact |
PutContact |
PUT |
/api/contact/id |
DeleteContact |
DELETE |
/api/contact/id |
http 四个主要的处理方法(get,put,post,delete)能够用来处理匹配增删改查操作:
Get 可以在服务端检索匹配URI匹配的资源,不会对服务器数据进行修改操作
Put 用户修改URI指定的特定资源,如果服务端允许,Put 也可以用户创建新的资源
Post 可以用于创建一个资源。服务端会为这个资源创建一个新的URI,并且将这个资源作为ResposeMessage 的一部分返回
Delete 用户删除URI匹配的资源
2. 创建一个工程
(1) 启动VS2012,在已经安装的模板中选择ASP.NET MVC4 Web 应用程序,单击确定
(2) 在ASP.NET MVC 4 项目对话框中选择 Web API,单击确定
(3) 添加一个Model,工程选择Models文件夹右键添加一个实体类,代码如下
{
public int ID { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
public DateTime Birthday { get; set; }
public int Age { get; set; }
}
(4) 添加一个数据操作接口
{
/// <summary>
/// 查询所有
/// </summary>
/// <returns></returns>
IEnumerable<Contact> GetListAll();
/// <summary>
/// 根据ID查询
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
Contact GetByID(int id);
/// <summary>
/// 添加
/// </summary>
/// <param name="contact"></param>
/// <returns></returns>
Contact Add(Contact contact);
/// <summary>
/// 根据ID删除
/// </summary>
/// <param name="id"></param>
void Remove(int id);
/// <summary>
/// 修改
/// </summary>
/// <param name="contact"></param>
/// <returns></returns>
bool Update(Contact contact);
}
(5) 添加数据操作接口实现类
{
private Log.Log log = Log.Log.Instance(typeof(ContactRep));
private List<Contact> list = new List<Contact>();
public ContactRep()
{
log.Info("执行构造方法");
list.Add(new Contact() { ID = 1, Age = 23, Birthday = Convert.ToDateTime("1977-05-30"), Name = "情缘", Sex = "男" });
list.Add(new Contact() { ID = 2, Age = 55, Birthday = Convert.ToDateTime("1937-05-30"), Name = "令狐冲", Sex = "男" });
list.Add(new Contact() { ID = 3, Age = 12, Birthday = Convert.ToDateTime("1987-05-30"), Name = "郭靖", Sex = "男" });
list.Add(new Contact() { ID = 4, Age = 18, Birthday = Convert.ToDateTime("1997-05-30"), Name = "黄蓉", Sex = "女" });
}
public IEnumerable<Contact> GetListAll()
{
return list;
}
public Contact GetByID(int id)
{
return list.Find(item => item.ID == id);
}
public Contact Add(Contact contact)
{
if (contact == null)
{
throw new NullReferenceException("空引用异常");
}
int maxid = list.Max(item => item.ID);
contact.ID = maxid + 1;
list.Add(contact);
return contact;
}
public void Remove(int id)
{
list.RemoveAll(item=>item.ID==id);
}
public bool Update(Contact contact)
{
if (contact == null)
{
throw new NullReferenceException("空引用异常");
}
Remove(contact.ID);
list.Add(contact);
return true;
}
}
(6)在Controllers文件中添加一个APIController
3. 获得一个资源
Action |
HTTP method |
Relative URI |
GetAllContact |
GET |
/api/contact |
GetContact |
GET |
/api/contact/id |
GetListBySex |
GET |
/api/contact?sex=sex |
获得所有联系人
{
return provider.GetListAll();
}
这个方法以Get开头,用于匹配Get方式请求,因为这个方法没有参数,所以这个方法将匹配/api/contact的请求
根据id获得联系人
{
Contact contact = provider.GetByID(id);
if (contact == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return contact;
}
这个方法也是以Get方式开头,而这个方法包含一个id参数,这个方法会匹配/api/contact/id 的请求,而请求中的参数id会自动转换为int类型
如果没有找到相应id的联系人,则会抛出一个HttpResponseMessage的异常,这个异常是指向的404异常,请求资源不存在。
根据性别获得资源
{
return provider.GetListAll().Where(item => item.Sex == sex);
}
如果一个请求中包含了一个查询的参数,web api 将尝试匹配/api/contact?sex=sex
4. 创建一个资源
客户端发送一个Post请求,会创建一个新的contact
{
contact = provider.Add(contact);
return contact;
}
为了处理post请求,我们需要声明一个以post开头的方法,方法中包含一个Contact类型的参数,这个参数从请求的body中序列化而来,所以客户端调用的时候传递的要是一个序列化过的Contact对象,序列化的格式可以是json,xml。
创建资源响应状态:
Response Code: 默认情况下,web api框架设置响应的状态为200(OK), 基于Http/1.1 协议,在使用post创建一个资源contact的时候,服务器响应状态为201 (Created)
Location: 当创建一个新的资源之后,我们需要 Response Headers 路径中包含一个URI。Web API框架将这个边的非常简单,看如下代码:
{
contact = provider.Add(contact);
HttpResponseMessage response = Request.CreateResponse<Contact>(HttpStatusCode.Created, contact);
string uri = Url.Link("", new { id = contact.ID });
response.Headers.Location = new Uri(uri);
return response;
}
这个方法返回的是一个HttpResponseMessage 而不是一个contact对象,我们可以获得请求响应的详细信息,包括状态码以及响应头信息。
使用CreateResponse可以创建一个HttpResonseMessage,并且会自动将Contact对象序列化写入响应Body中。
5. 修改一个资源
{
contact.ID = id;
bool flag = provider.Update(contact);
if (!flag)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
方式是以Put开头,当请求Mehtod 为Put,这个请求将匹配这个方法,方法中包含了两个参数,这两个参数来自URI请求参数和Request Body 中
6. 删除一个资源
{
provider.Remove(id);
throw new HttpResponseException(HttpStatusCode.NoContent);
}
删除基本和上面都一样了,只是请求method 不一样而已,这里不再累述客户端调用参考上一章说明代码
相关参考文章链接
1. Web API简单说明
近来很多大型的平台都公开了Web API。比如百度地图 Web API,做过地图相关的人都熟悉。公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过在浏览器中使用 JavaScript来创建更丰富的HTML体验。所以我相信Web API会越来越有它的用武之地。
说道Web API很多人都会想到Web服务,但是他们仍然有一定的区别:Web API服务是通过一般的 HTTP公开了,而不是通过更正式的服务合同 (如SOAP)
2. ASP.NET Web API简介
ASP. NET Web API支持让你能够轻松地创建功能强大的 Web API,可以从范围广泛的客户端 (包括使用 JavaScript从浏览器中,到任何移动/客户端平台上的本机应用程序)访问。它提供以下支持:
(1)现代 HTTP 的编程模型:在你的 Web 应用程序中直接访问和处理 HTTP 请求并响应,使用清洁、 强类型的 HTTP 对象模型。除了在服务器上支持这个 HTTP 的编程模型之外,通过使用新的 HttpClient API来从任何.NET 应用程序中调用 Web ApI,我们也支持客户端中相同的编程模型。
(2)内容协商: Web API 有对内容协商的内置支持 — — 这使客户端和服务器一起工作以决定从一个 API 返回的正确的数据格式。我们为JSON、 XML 和Form URL 编码的格式提供默认支持,并可以通过添加你自己的格式化程序来扩展这种支持,或者甚至用你自己的来替换默认的内容协商策略。
(3)查询组成: Web API 通过 OData URL 公约使你能够轻松地支持查询。当你从你的 Web API 返回一种类型的 IQueryable <T> 时,框架将自动为它提供 OData 查询支持— — 使其易于分页和排序。
(4)模型绑定和验证:模型绑定器提供了一种简单的方法来从HTTP 请求中的不同部分提取数据,并将这些信息部分转换为Web API行为可使用的.NET对象。Web API 支持相同的模型绑定和ASP. NET MVC 现今支持的验证基础结构。
(5)路由: Web ApI 支持完整的路由功能集。现今ASP. NET MVC 和 ASP.NET也支持这一点,包括路线参数和约束。默认情况下,Web API 还提供了智能公约,使你能够轻松地创建实现 Web ApI的类,而无需不得不将属性应用到你的类或方法中。Web API 的配置纯粹是通过代码来实现的 — — 保持你的配置文件干净。
(6)筛选器: Web ApI 使你能够轻松地使用和创建筛选器 (例如: [授权]),那样你能够封装和应用交叉行为。
(7)改进的可测试性: 与其在静态文本对象中设置 HTTP 的详细信息,不如将 Web API 行为与 HttpRequestMessage 和 HttpResponseMessage 一起使用— — 两个新 的HTTP对象 (在其他内) 使测试更容易。例如,你可以单元测试你的 Web ApI,而无需不得不使用 Mocking 框架。
(8)IoC支持: Web API 支持由 ASP. NET MVC 实现的服务定位器模式,使你能够解决不同设备的依赖。你可以轻松地使用IoC容器或依赖注射架构来集成,以保持干净的依赖解决方案。
(9)灵活的托管: Web ApI可以托管在任何类型的 ASP.NET应用程序内 (包括这两个基于应用程序的ASP. NET MVC和ASP.NET Web Forms)。我们还设计了 Web API 支持,这样,你还可以选择在你自己的进程内托管/公开它们,如果你不想使用 ASP.NET/IIS 来这样做。至于你如何以及在哪儿使用它,这给了你最大的灵活性。3. 创建一个Web API程序
启动VS2012创建一个新项目,在已经安装的模板中选择 ASP.NET MVC4 Web API程序
在ASP.NET MVC项目对话框中选择Web API项,点击确定
创建成功之后工程中会自动添加一个Web API服务控制器,上面并附带访问地址
项目解决方案,选择Models文件夹右键 添加一个Model类
代码如下:
{
public class Contact
{
public int ID { get; set; }
public string Name { get; set; }
public string Sex { get; set; }
public DateTime Birthday { get; set; }
public int Age { get; set; }
} }
工程解决方案选择Controllers文件夹右键添加一个新的Web API controller
在添加控制器弹出对话框中选择模板: 空API控制器
控制器中添加如下代码:
{
public class ContactController : ApiController
{
Contact[] contacts = new Contact[]
{
new Contact(){ ID=1, Age=23, Birthday=Convert.ToDateTime("1977-05-30"), Name="情缘", Sex="男"},
new Contact(){ ID=2, Age=55, Birthday=Convert.ToDateTime("1937-05-30"), Name="令狐冲", Sex="男"},
new Contact(){ ID=3, Age=12, Birthday=Convert.ToDateTime("1987-05-30"), Name="郭靖", Sex="男"},
new Contact(){ ID=4, Age=18, Birthday=Convert.ToDateTime("1997-05-30"), Name="黄蓉", Sex="女"},
};
/// <summary>
/// /api/Contact
/// </summary>
/// <returns></returns>
public IEnumerable<Contact> GetListAll()
{
return contacts;
}
/// <summary>
/// /api/Contact/id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Contact GetContactByID(int id)
{
Contact contact = contacts.FirstOrDefault<Contact>(item=>item.ID==id);
if (contact == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return contact;
}
/// <summary>
/// 根据性别查询
/// /api/Contact?sex=女
/// </summary>
/// <param name="sex"></param>
/// <returns></returns>
public IEnumerable<Contact> GetListBySex(string sex)
{
return contacts.Where(item => item.Sex == sex);
}
}}
4. 浏览器访问API路径
Controller Methed
URI
GetListAll
/api/Contact
GetListBySex
"/api/Contact?sex=" + sex
GetContactByID
/api/Contact/"+id
在IE浏览器中浏览出现如下效果
如果在Chrome 或者 FireFox 中浏览会先下如下效果5. Javascript访问Web API
在项目中添加一个About View视图
代码如下:
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>About</title>
<script type="text/javascript" src="/Scripts/jquery-1.7.1.min.js"></script>
<script type="text/ecmascript">
$(document).ready(function () {
$("#btnAll").click(function () {
$.getJSON("/api/Contact", function (data) {
var html = "<ul>";
$(data).each(function (i, item) {
html += "<li>"+item.ID+":"+item.Name+":"+item.Sex+"</li>";
});
html += "</ul>";
$("#contactAll").html(html);
});
});
$("#btnID").click(function () {
var id = $("#txtID").val();
$.getJSON("/api/Contact/"+id, function (data) {
var html = "<ul>";
$(data).each(function (i, item) {
html += "<li>" + item.ID + ":" + item.Name + ":" + item.Sex + "</li>";
});
html += "</ul>";
$("#contactID").html(html);
});
});
$("#btnSex").click(function () {
var sex = $("#ddlSex").val();
$.getJSON("/api/Contact?sex=" + sex, function (data) {
var html = "<ul>";
$(data).each(function (i, item) {
html += "<li>" + item.ID + ":" + item.Name + ":" + item.Sex + "</li>";
});
html += "</ul>";
$("#contactSex").html(html);
});
});
});
</script>
</head>
<body>
<p>
<input type="button" id="btnAll" value="查询所有" />
</p>
<p>
<input type="text" id="txtID" name="txtID"/>
<input type="button" id="btnID" value="根据ID查询" />
</p>
<p>
<select id="ddlSex" name="ddlSex">
<option value="男">男</option>
<option value="女">女</option>
</select>
<input type="button" id="btnSex" value="根据性别查询" />
</p>
<div id="contactAll">
</div>
<div id="contactID">
</div>
<div id="contactSex">
</div>
</body>
</html>
运行结果效果图
6. Web API总结
1.Web API 控制器(Controller) 继承ApiController
2. Api 的 Url Map: api/{controller}/{id} 每个"Action"是通过 Http谓词(GET/POST/PUT/DELETE)映射的
3.客户端可以通过 Http Header 的 Accept 指定返回数据的格式。默认是支持:appliction/xml 和 application/json,当想返回比如 image/jpeg 这样的图片格式时,需要添加 MediaTypeFormatter 。比如:当指定某个 Task 时,通过指定 Accept : image/jpeg 获取该 Task 的图片信息。(后面详细介绍)
该系列大概20篇左右,期待各位的拍砖!