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 操作:

  1. GET就是在指定的URI中检索资源的表现形式。get在服务器段不会有任何的影响。
  2. PUT就是在指定的URI中更新一个资源。如果服务端允许客户端指定新的URIs,那么PUT在一个指定的URI中也能被用来创建一个新的资源。对于本教程,针对PUT的API将不能创建新资源。
  3. POST就是创建一个新的资源。服务端将分配给新对象一个URI,并且返回这个URI响应消息的一部分。
  4. 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;
}

请注意这个方法的两个事情:

  1. 这个方法的名字以“Post”开头,为了创建一个新的产品,这个客户端将发送一个HTTP Post请求。
  2. 这个方法采用类型为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操作)第二课的更多相关文章

  1. ASP.NET Core Web API Cassandra CRUD 操作

    在本文中,我们将创建一个简单的 Web API 来实现对一个 “todo” 列表的 CRUD 操作,使用 Apache Cassandra 来存储数据,在这里不会创建 UI ,Web API 的测试将 ...

  2. ASP.NET Web API 基本操作(CRUD)

    上一篇介绍了ASP.NET Web API的基本知识和原理,这一篇我们通过一个更直观的实例,对产品进行CRUD操作(Create/Read/Update/Delete)来继续了解一下它的基本应用. 创 ...

  3. Asp.Net Web API 2第十二课——Media Formatters媒体格式化器

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本教程演示如何在ASP.N ...

  4. Asp.Net Web API 2第十八课——Working with Entity Relations in OData

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html. 本文的示例代码的下载地址 ...

  5. 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. 本文主要来讲解以下内容: ...

  6. Asp.Net Web API 2第十五课——Model Validation(模型验证)

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文参考链接文章地址htt ...

  7. Asp.Net Web API 2第十四课——Content Negotiation(内容协商)

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...

  8. Asp.Net Web API 2

    Asp.Net Web API 2第十八课——Working with Entity Relations in OData   前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导 ...

  9. 【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 ...

随机推荐

  1. JS日期时间选择器

    本文介绍一种日期和时间选择器的使用方法.此选择器由jqueryUI实现,支持精确到毫秒的时间选择. 此选择器项目地址为http://trentrichardson.com/examples/timep ...

  2. iOS ... NS_REQUIRES_NIL_TERMINATION

    看到官方的一个样例不错,这里留记. #import <Cocoa/Cocoa.h> @interface NSMutableArray (variadicMethodExample) - ...

  3. Intel 80x86 寻址模式

    随着进一步的研究,我们会逐渐接触到你的电脑配置模式的内在联系,和设计原则.在这些,解决计算机是一个非常重要的概念,我们需要很好地理解了什么. 一.预赛: (1)作数 在接触寻址方式之前,我们还要先了解 ...

  4. gcd&&lcm

    1011 最大公约数GCD 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 输入2个正整数A,B,求A与B的最大公约数.   Input 2个数A,B,中 ...

  5. Windows RPC

    转载 Windows RPC Demo实现 本文参考并整理以下相关文章 1. <远程过程调用> -百度百科 2. <RPC 编程> -http://www.ibm.com/de ...

  6. 【Head First Javascript】学习笔记0——自己制作chm参考手册素材

    变量声明:var 常量声明:const 数据格式转换: 1.转换函数 parseInt(A):把字符串A转换成整数:其中A为只包含数字的字符串 parseFloat(A):把字符串A转换成浮点数:其中 ...

  7. jg-table 过程2 ( jgTable )

    jg-table ( jgTable )  添加一些新的功能,这是多行表头支持,要添加到,现在支持拖放多行表来改变头部的宽度, 假设设置cloneTheadToFoot 能够自己主动翻转多行表头,这也 ...

  8. Oracle 11g 环境,使用utl_smtp创建一个存储过程来发送邮件

    太多的在线电子邮件存储过程.我不转发,弄个作为一个简单的例子演示. create or replace procedure Send_mail(mail_body varchar2) is smtp_ ...

  9. PHP+百度地图API+JAVASCRIPT实现GPS坐标与百度坐标转换的实例

    原文:PHP+百度地图API+JAVASCRIPT实现GPS坐标与百度坐标转换的实例 <!--小幅的坐标转换点位程序--> <!DOCTYPE html> <html&g ...

  10. R.layout.main connot be resolved 和R.java消失

    出现例如以下问题: 鼠标放到出代码上面: 分析问题: 1.查看R文件是否被生成.假设没有生成,则勾选build Automatically,然后Clean: 2.假设R文件已生成.则删除去掉代码中: ...