Asp.Net Web API 2(CRUD操作)第二课
Asp.Net Web API 2(CRUD操作)第二课
Asp.Net Web API 导航
Asp.Net Web API第一课:入门http://www.cnblogs.com/aehyok/p/3432158.html
前言
CRUD代表着 Create、Read、Update、Delete,这是四个基本的数据库操作。许多HTTP服务模型也通过Rest或者Rest-like APIs实现CRUD操作。
在本教程中,我将建立一个非常简单的Web API来管理一个产品列表,和第一课中的Model是一样的,同样每个产品包括名称、价格和类别(如玩具或硬盘),在加上一个产品的ID。
本次教程的开发工具使用的仍然是VS2013。
这个产品的API将包含如下几个方法。

请注意某些Uri路径中包含产品ID。例如,为得到ID为28的这个产品,客户端将发送一个Get请求:http://hostname/api/products/28。
这个产品的API定义了两个资源类型的Uri

这四个主要的 HTTP 方法(GET、PUT、POST 和 DELETE)可以映射到以下的 CRUD 操作:
- GET就是在指定的URI中检索资源的表现形式。get在服务器段不会有任何的影响。
- PUT就是在指定的URI中更新一个资源。如果服务端允许客户端指定新的URIs,那么PUT在一个指定的URI中也能被用来创建一个新的资源。对于本教程,针对PUT的API将不能创建新资源。
- POST就是创建一个新的资源。服务端将分配给新对象一个URI,并且返回这个URI响应消息的一部分。
- DELETE 就是在指定的URI中删除一个资源。
请注意:其中的PUT方法将替换掉产品的整个实体。也就是说,客户端被期望发送一个完整的被更新产品实体信息。如果你想支持部分更新,这个PATCH方法可以被选择。在本教程中,PATCH方法将不会得到支持。
在这个教程当中我将会使用VS2013来创建一个简单的示例。提供本文项目示例下载链接http://pan.baidu.com/s/1ePYLw
创建一个新的 Web API项目
关于创建项目,如果您不太清楚,可以查看第一课中相关内容介绍,当然本教程创建的项目和上一课中的又有所区别。

添加一个Model
这个模型和上一次课程中的也是保持一致。
直接上代码

namespace WebAPI.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}

添加一个Repository
首先我们需要存储产品的集合。分开收集我们的服务实现是一个好的主意。这种方式,我们可以改变后备存储,而不用修改服务类的实现。这种模式的设计叫做仓储模式。首先建立一个接口。

namespace WebAPI.Models
{
interface IProductRepository
{
IEnumerable<Product> GetAll();
Product Get(int id);
Product Add(Product item);
void Remove(int id);
bool Update(Product item);
}
}

暂时我们把接口和实体类放在了一个文件夹下。现在在Models文件夹下添加另外一个类,这个类将集成IProductRepository接口。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace WebAPI.Models
{
public class ProductRepository
{
private List<Product> products = new List<Product>();
private int _nextId = 1; public ProductRepository()
{
Add(new Product { Name = "Tomato soup", Category = "Groceries", Price = 1.39M });
Add(new Product { Name = "Yo-yo", Category = "Toys", Price = 3.75M });
Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M });
} public IEnumerable<Product> GetAll()
{
return products;
} public Product Get(int id)
{
return products.Find(p => p.Id == id);
} public Product Add(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = _nextId++;
products.Add(item);
return item;
} public void Remove(int id)
{
products.RemoveAll(p => p.Id == id);
} public bool Update(Product item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
int index = products.FindIndex(p => p.Id == item.Id);
if (index == -1)
{
return false;
}
products.RemoveAt(index);
products.Add(item);
return true;
}
}
}

添加一个Web API控制器
如果你已经使用过Asp.Net MVC,那么你已经很熟悉控制器了。在Asp.Net Web API,一个控制器就是一个处理来自客户端的HTTP请求的一个class。
有关如何添加控制器的也可以参见第一课中的内容,在这里就不进行过多的介绍了。直接添加一个ProductsController。
添加一个包含IProductRepository实例的字段。
public class ProductsController : ApiController
{
static readonly IProductRepository repository = new ProductRepository();
}
在控制器中调用new ProductRepository不是最好的设计,因为它关系到特定的实现的IProductRepository控制器。更好的方法,请参阅之后有关依赖注入的文章介绍。
下面进行一一列举每个HTTP方法。
第一个:为了得到所有的产品信息列表,在控制器中添加的方法如下:
public IEnumerable<Product> GetAllProducts()
{
return repository.GetAll();
}
这个方法的名称是以Get开头,所以通过约定它映射为Get请求。此外,因为不包含参数,它映射到一个不包含在路径中的id线段的URI。
第二个:通过产品ID获取一个产品信息,在控制器中添加的方法如下:

public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}

这个方法的名称是以Get开头,但是这个方法有一个名字为id的参数。这个参数被映射到URI路径中的id一段。这个Asp.Net Web API框架自动把ID参数转换为正确的int数据类型。
如果id无效,那么就会抛出一个HttpReponseException的异常。此异常将由框架转换成一个404错误。
第三个:按照类别查找产品信息,在控制器中添加的方法如下:
public IEnumerable<Product> GetProductsByCategory(string category)
{
return repository.GetAll().Where(
p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));
}
如果请求的URI中包含查询字符串,这个WebApi试图在控制器方法的参数中来匹配查询字符串。因此,窗体中的“api/products?category=category”的URI将映射到此方法。
第四个:添加一个新的产品,在控制器中添加的方法如下:
public Product PostProduct(Product item)
{
item = repository.Add(item);
return item;
}
请注意这个方法的两个事情:
- 这个方法的名字以“Post”开头,为了创建一个新的产品,这个客户端将发送一个HTTP Post请求。
- 这个方法采用类型为Product的参数。在Web Api中复杂类型的参数是从请求消息体中反序列化得来的。因此,我们期望客户端发送xml或者Json格式的一个产品对象的序列化表现形式。
此实现会工作,但它还很不完整。理想情况下,我们希望的 HTTP 响应,包括以下内容:
- 响应代码:在默认情况下,这个Web API框架设置响应状态码为200(OK)。但是根据这个HTTP/1.1协议,当POST请求在创建一个资源时,这个服务端应该回复状态201(Created)。
- 位置:当服务端创建一个资源时,它应该在响应的Location标头中包含这个资源的URI。
Asp.Net Web API使它容易操作HTTP响应消息。这是改善后的代码:

public HttpResponseMessage PostProduct(Product item)
{
item = repository.Add(item);
var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item); string uri = Url.Link("DefaultApi", new { id = item.Id });
response.Headers.Location = new Uri(uri);
return response;
}

请注意:此方法返回类型现在是HttpResponseMessage。通过返回HttpResponseMessage而不是产品,我们可以控制的 HTTP 响应消息,包括状态代码和位置标头的详细信息。
CreateResponse 方法将会创建 HttpResponseMessage,并自动将 Product 对象的序列化表示形式写入到响应消息的正文中。
此示例不会验证该
Product。模型验证有关的信息,请参见Asp.Net Web API 模型验证。(暂未实现)
第四个:通过PUT更新产品,在控制器添加的代码如下:

public void PutProduct(int id, Product product)
{
product.Id = id;
if (!repository.Update(product))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}

方法名称以Put开头,这样 Web API 就能够将其与 PUT 请求相匹配。这个方法有两个参数,一个是产品ID和更新的产品。ID参数是从URI中获得的,product参数是从请求正文反序列化得来的。默认情况下,ASP.NET Web API 框架从路由获取简单的参数类型,从请求正文获取复杂的类型。
第五个:删除产品,在控制器添加的代码如下:

public void DeleteProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
} repository.Remove(id);
}

如果删除请求成功,它可以返回状态 200 (OK) 与实体的描述该状态 ;如果删除仍然挂起,则返回状态 202 (已接受);或状态与没有实体正文 204 (无内容)。在这种情况下, DeleteProduct方法具有void返回类型,因此 ASP.NET Web API 自动转换此状态代码 204 (无内容)。
总结
在本次教程中,主要来探讨Wep API中的CRUD操作,针对前台的如何调用,这个在第一课中也有简单的使用。
本次教程参考的主要文章链接为:http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations
Asp.Net Web API 2(CRUD操作)第二课的更多相关文章
- ASP.NET Core Web API Cassandra CRUD 操作
在本文中,我们将创建一个简单的 Web API 来实现对一个 “todo” 列表的 CRUD 操作,使用 Apache Cassandra 来存储数据,在这里不会创建 UI ,Web API 的测试将 ...
- ASP.NET Web API 基本操作(CRUD)
上一篇介绍了ASP.NET Web API的基本知识和原理,这一篇我们通过一个更直观的实例,对产品进行CRUD操作(Create/Read/Update/Delete)来继续了解一下它的基本应用. 创 ...
- Asp.Net Web API 2第十二课——Media Formatters媒体格式化器
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本教程演示如何在ASP.N ...
- Asp.Net Web API 2第十八课——Working with Entity Relations in OData
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文的示例代码的下载地址 ...
- Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文主要来讲解以下内容: ...
- Asp.Net Web API 2第十五课——Model Validation(模型验证)
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文参考链接文章地址htt ...
- Asp.Net Web API 2第十四课——Content Negotiation(内容协商)
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...
- Asp.Net Web API 2
Asp.Net Web API 2第十八课——Working with Entity Relations in OData 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导 ...
- 【ASP.NET Web API教程】2.3 与实体框架一起使用Web API
原文:[ASP.NET Web API教程]2.3 与实体框架一起使用Web API 2.3 Using Web API with Entity Framework 2.3 与实体框架一起使用Web ...
随机推荐
- Codeforces Round #191 (Div. 2)---A. Flipping Game
Flipping Game time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- ASP.NET AJAX简明教程
当我们谈论Ajax时,首先想到的就是JavaScript下的Ajax,用来完成网页的交互,局部刷新工作,Microsoft的ASP.NET AJAX框架在Web的开发中承担着类似的角色,并简化了Ja ...
- 沃森Mysql数据库修复工具
华信Mysql数据库修复程序是由北京华信数据恢复中心独立研发.主要针对Mysql数据库损坏的恢复. 本程序可用于因为各种误操作而导致数据丢失的恢复,以及因为断电.陈列损坏.硬盘坏道等各种原因导致数据库 ...
- ASPNETPager常用属性
<webdiyer:AspNetPager ID="pager" runat="server" class="page" FirstP ...
- bigdata_Hadoop jps出现process information unavailable提示解决办法
启动Hadoop之后,使用jps命令查看当前系统的java进程情况,显示: hduser@jack:/usr/local/hadoop$ jps 18470 SecondaryNameNode 190 ...
- IronPython和C#交互
IronPython和C#交互 IronPython是一个.NET平台上的Python实现,包括了完整的编译器.执行引擎与运行时支持,能够与.NET已有的库无缝整合到一起. IronPython已经很 ...
- linux_常用命令_(ls, lsof,nslookup)_查看文件按照时间排序
平时收集些用到的命令 方便使用 1: ls -lrt 按时间排序 展示 2:nslookup 查看dns解析 3:lsof -p 进程号 lsof `which httpd` //那个进程在使用 ...
- Xcode6为什么干掉pch(Precompile Prefix Header)&怎样加入pch文件
一直在用xcode6开发,但项目都是在xcode5上创建的,所以一直没注意到,xcode6居然干掉pch文件了. 为什么xcode6没有自己主动创建pch文件呢? 简单地看:我们在写项目的时候,大部分 ...
- JavaScript闭包的一些理解
原文:JavaScript闭包的一些理解 简单一点的说:闭包就是能够读取其他函数内部变量的函数.那如何实现读取其它函数内部变量呢,大家都知道在JavaScript中内部函数可以访问其父函数中的变量,那 ...
- HDU 2544-最短路(最短路spfa)
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...