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

  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:IproductRepository
    {
        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

时间: 2024-08-19 04:14:06

Asp.Net Web API 2第二课——CRUD操作的相关文章

Asp.Net Web API 2第一课——入门

原文:Asp.Net Web API 2第一课--入门 前言 Http不仅仅服务于Web Pages.它也是一个创建展示服务和数据的API的强大平台.Http是简单的.灵活的.无处不在的.你能想象到几乎任何的平台都会有HTTP服务库.HTTP服务可以涉及到范围广泛的客户端,包括浏览器.各种移动设备和传统的桌面应用程序. Asp.Net Web API是在.NET Framework框架上用于建立Web APIs的一个框架.在这个教程中,你将会使用Asp.Net Web API框架来创建一个能够返

Asp.Net Web API 2第九课——自承载Web API

原文:Asp.Net Web API 2第九课--自承载Web API 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html Asp.Net Web API可以需要IIS.你可以在你自己的主机上来承载一个Web API. 本教程来展示在控制台应用程序中来承载一个Web API.使用的开发工具为VS2013. 本文示例代码下载链接http://pan.baidu.com/s/1d

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

原文:Asp.Net Web API 2第十二课--Media Formatters媒体格式化器 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本教程演示如何在ASP.NET Web API中支持额外的媒体格式. Internet Media Types--Internet的媒体类型 媒体类型,也叫做MIME类型,标识了一片数据的格式.在HTTP中,媒体类型描述了消息体

Asp.Net Web API 2第十一课——在Web API中使用Dependency Resolver

原文:Asp.Net Web API 2第十一课--在Web API中使用Dependency Resolver 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文主要来介绍在Asp.Net Web API使用Web API的Decpendency Resolver在控制器中如何注入依赖. 本文使用VS2013.本文的示例代码下载链接为http://pan.baidu.

Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中]

原文:Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中] 前言 本来一直参见于微软官网进行学习的, 官网网址http://www.asp.net/web-api.出于自己想锻炼一下学习阅读英文文章的目的,又可以学习下微软新发布的技术,其实也很久了,但自己菜鸟一枚,对自己来说都是新技术了.鉴于以上两个原因,本人打算借助google翻译和有道词典,来翻译学习这个系列,并通过博客园来记录自己的翻译学习过程.由于自己阅读水平的确太菜,在借助工具的情况下,有时候搞出来的也是蹩脚的语句,

Asp.Net Web API 2第四课——HttpClient消息处理器

原文:Asp.Net Web API 2第四课--HttpClient消息处理器 Asp.Net Web API 导航   Asp.Net Web API第一课:入门http://www.cnblogs.com/aehyok/p/3432158.html       Asp.Net Web API第二课:CRUD操作http://www.cnblogs.com/aehyok/p/3434578.html       Asp.Net Web API第三课:.NET客户端调用Wep API http

Asp.Net Web API 2第五课——Web API路由

原文:Asp.Net Web API 2第五课--Web API路由 Asp.Net Web API 导航   Asp.Net Web API第一课--入门 http://www.cnblogs.com/aehyok/p/3432158.html       Asp.Net Web API第二课--CRUD操作 http://www.cnblogs.com/aehyok/p/3434578.html       Asp.Net Web API第三课--.NET客户端调用Web API http:

Asp.Net Web API 2第六课——Web API路由和动作选择

原文:Asp.Net Web API 2第六课--Web API路由和动作选择 Asp.Net Web API 导航       Asp.Net Web API第一课--入门http://www.cnblogs.com/aehyok/p/3432158.html       Asp.Net Web API第二课--CRUD操作http://www.cnblogs.com/aehyok/p/3434578.html       Asp.Net Web API第三课--.NET客户端调用Web AP

实战 ASP.NET Web API

Web API 框架是一个面向 Http 协议的通信框架.相对于 WCF 而言,Web API 只面向于 Http 协议设计,而且没有 WCF 那么繁琐的配置.Web API 的开发类似于 ASP.NET MVC 中控制器的开发,但是相对于直接使用 ASP.NET MVC 来返回 Json 对象的方式而言,Web API 封装了数据的序列化.反序列化,接口.实现都更加简单.  简单地说,如果要向浏览器.移动端提供 Json 数据格式的 API,则应该首选 Web API 作为通信框架. 以下,我