1.WebApi是什么

ASP.NET Web API 是一种框架,用于轻松构建可以由多种客户端(包括浏览器和移动设备)访问的 HTTP 服务。ASP.NET Web API 是一种用于在 .NET Framework 上构建 RESTful 应用程序的理想平台。

可以把WebApi看成Asp.Net项目类型中的一种,其他项目类型诸如我们熟知的WebForm项目,Windows窗体项目,控制台应用程序等。

WebApi类型项目的最大优势就是,开发者再也不用担心客户端和服务器之间传输的数据的序列化和反序列化问题,因为WebApi是强类型的,可以自动进行序列化和反序列化,一会儿项目中会见到。

下面我们建立了一个WebApi类型的项目,项目中对产品Product进行增删改查,Product的数据存放在List<>列表(即内存)中。

2.页面运行效果

如图所示,可以添加一条记录; 输入记录的Id,查询出该记录的其它信息; 修改该Id的记录; 删除该Id的记录。

3.二话不说,开始建项目

1)新建一个“ASP.NET MVC 4 Web 应用程序”项目,命名为“ProductStore”,点击确定

2)选择模板“Web API”,点击确定

3)和MVC类型的项目相似,构建程序的过程是先建立数据模型(Model)用于存取数据, 再建立控制器层(Controller)用于处理发来的Http请求,最后构造显示层(View)用于接收用户的输入和用户进行直接交互。

3)和MVC类型的项目相似,构建程序的过程是先建立数据模型(Model)用于存取数据, 再建立控制器层(Controller)用于处理发来的Http请求,最后构造显示层(View)用于接收用户的输入和用户进行直接交互。

这里我们先在Models文件夹中建立产品Product类: Product.cs,如下:

  1. namespace ProductStore.Models
  2. {
  3. public class Product
  4. {
  5. public int Id { get; set; }
  6. public string Name { get; set; }
  7. public string Category { get; set; }
  8. public decimal Price { get; set; }
  9. }
  10. }

4)试想,我们目前只有一个Product类型的对象,我们要编写一个类对其实现增删改查,以后我们可能会增加其他的类型的对象,再需要编写一个对新类型的对象进行增删改查的类,为了便于拓展和调用,我们在Product之上构造一个接口,使这个接口约定增删改查的方法名称和参数,所以我们在Models文件夹中新建一个接口:  IProductRepository.cs ,如下:

  1. using System.Collections.Generic;
  2.  
  3. namespace ProductStore.Models
  4. {
  5. interface IProductRepository
  6. {
  7. IEnumerable<Product> GetAll();
  8. Product Get(int id);
  9. Product Add(Product item);
  10. void Remove(int id);
  11. bool Update(Product item);
  12. }
  13. }

5)然后,我们实现这个接口,在Models文件夹中新建一个类,具体针对Product类型的对象进行增删改查存取数据,并在该类的构造方法中,向List<Product>列表中存入几条数据,这个类叫:ProductRepository.cs,如下:

  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. namespace ProductStore.Models
  5. {
  6. public class ProductRepository
  7. {
  8. private List<Product> products = new List<Product>();
  9. private int _nextId = ;
  10. public ProductRepository()
  11. {
  12. Add(new Product { Name = "Tomato soup", Category = "Groceries", Price = 1.39M });
  13. Add(new Product { Name = "Yo-yo", Category = "Toys", Price = 3.75M });
  14. Add(new Product { Name = "Hammer", Category = "Hardware", Price = 16.99M });
  15. }
  16.  
  17. public IEnumerable<Product> GetAll()
  18. {
  19. return products;
  20. }
  21.  
  22. public Product Get(int id)
  23. {
  24. return products.Find(p => p.Id == id);
  25. }
  26.  
  27. public Product Add(Product item)
  28. {
  29. if (item == null)
  30. {
  31. throw new ArgumentNullException("item");
  32. }
  33. item.Id = _nextId++;
  34. products.Add(item);
  35. return item;
  36. }
  37.  
  38. public void Remove(int id)
  39. {
  40. products.RemoveAll(p => p.Id == id);
  41. }
  42.  
  43. public bool Update(Product item)
  44. {
  45. if (item == null)
  46. {
  47. throw new ArgumentNullException("item");
  48. }
  49. int index = products.FindIndex(p => p.Id == item.Id);
  50. if (index == -)
  51. {
  52. return false;
  53. }
  54. products.RemoveAt(index);
  55. products.Add(item);
  56. return true;
  57. }
  58.  
  59. }
  60. }

此时,Model层就构建好了。

6)下面,我们要构建Controller层,在此之前,先回顾一下Http中几种请求类型,如下

get  类型

用于从服务器端获取数据,且不应该对服务器端有任何操作和影响

post 类型

用于发送数据到服务器端,创建一条新的数据,对服务器端产生影响

put 类型

用于向服务器端更新一条数据,对服务器端产生影响 (也可创建一条新的数据但不推荐这样用)

delete 类型

用于删除一条数据,对服务器端产生影响

这样,四种请求类型刚好可对应于对数据的查询,添加,修改,删除。WebApi也推荐如此使用。在WebApi项目中,我们请求的不再是一个具体页面,而是各个控制器中的方法(控制器也是一种类,默认放在Controllers文件夹中)。下面我们将要建立一个ProductController.cs控制器类,其中的方法都是以“Get Post Put Delete”中的任一一个开头的,这样的开头使得Get类型的请求发送给以Get开头的方法去处理,Post类型的请求交给Post开头的方法去处理,Put和Delete同理。

而以Get开头的方法有好几个也是可以的,此时如何区分到底交给哪个方法执行呢?这就取决于Get开头的方法们的传入参数了,一会儿在代码中可以分辨。

构建Controller层,在Controllers文件夹中建立一个ProductController.cs控制器类,如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using ProductStore.Models;
  5. using System.Web.Http;
  6. using System.Net;
  7. using System.Net.Http;
  8.  
  9. namespace ProductStore.Controllers
  10. {
  11. public class ProductController : ApiController
  12. {
  13. static readonly ProductRepository repository = new ProductRepository();
  14.  
  15. //GET: /api/products
  16. public IEnumerable<Product> GetAllProducts()
  17. {
  18. return repository.GetAll();
  19. }
  20.  
  21. //GET: /api/products/id
  22. public Product GetProduct(int id)
  23. {
  24. Product item = repository.Get(id);
  25. if (item == null)
  26. {
  27. throw new HttpResponseException(HttpStatusCode.NotFound);
  28. }
  29. return item;
  30. }
  31.  
  32. //GET: /api/products?category=category
  33. public IEnumerable<Product> GetProductsByCategory(string category)
  34. {
  35. return repository.GetAll().Where(p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));
  36. }
  37.  
  38. //POST: /api/products
  39. public HttpResponseMessage PostProduct(Product item)
  40. {
  41. item = repository.Add(item);
  42.  
  43. var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item);
  44. string uri = Url.Link("DefaultApi", new { id = item.Id });
  45. response.Headers.Location = new Uri(uri);
  46.  
  47. return response;
  48. }
  49.  
  50. //PUT: /api/products/id
  51. public void PutProduct(int id, Product product)
  52. {
  53. product.Id = id;
  54. if (!repository.Update(product))
  55. {
  56. throw new HttpResponseException(HttpStatusCode.NotFound);
  57. }
  58. }
  59.  
  60. //Delete: /api/products/id
  61. public void DeleteProduct(int id)
  62. {
  63. Product item = repository.Get(id);
  64. if (item == null)
  65. {
  66. throw new HttpResponseException(HttpStatusCode.NotFound);
  67. }
  68. repository.Remove(id);
  69. }
  70. }
  71. }

使该类继承于ApiController类,在其中实现处理各种Get,Post,Put,Delete类型Http请求的方法。每一个方法前都有一句注释,标识了该方法的针对的请求的类型(取决于方法的开头),以及要请求到该方法,需要使用的url。

这些url是有规律的,见下:

Action

HTTP method

Relative URI

Get a list of all products

GET

/api/products

Get a product by ID

GET

/api/products/id

Get a product by category

GET

/api/products?category=category

Create a new product

POST

/api/products

Update a product

PUT

/api/products/id

Delete a product

DELETE

/api/products/id

api是必须的,products对应的是ProductsControllers控制器,然后又Http请求的类型和url的后边地址决定。

这里,我们除了第三个“Get a product by category”,其他方法都实现了。

7)最后,我们来构建View视图层,我们更改Views文件夹中的Home文件夹下的Index.cshtml文件,这个文件是项目启动页,如下:

  1. <div id="body">
  2. <script src="~/Scripts/jquery-1.10.2.min.js"></script>
  3. <section>
  4. <h2>添加记录</h2>
  5. Name:<input id="name" type="text" /><br />
  6. Category:<input id="category" type="text" />
  7. Price:<input id="price" type="text" /><br />
  8. <input id="addItem" type="button" value="添加" />
  9. </section>
  10.  
  11. <section>
  12. <br />
  13. <br />
  14. <h2>修改记录</h2>
  15. Id:<input id="id2" type="text" /><br />
  16. Name:<input id="name2" type="text" /><br />
  17. Category:<input id="category2" type="text" />
  18. Price:<input id="price2" type="text" /><br />
  19. <input id="showItem" type="button" value="查询" />
  20. <input id="editItem" type="button" value="修改" />
  21. <input id="removeItem" type="button" value="删除" />
  22. </section>
  23.  
  24. </div>

8)然后我们给页面添加js代码,对应上面的按钮事件,用来发起Http请求,如下:

  1. <script>
  2. //用于保存用户输入数据
  3. var Product = {
  4. create: function () {
  5. Id: "";
  6. Name: "";
  7. Category: "";
  8. Price: "";
  9. return Product;
  10. }
  11. }
  12.  
  13. //添加一条记录 请求类型:POST 请求url: /api/Products
  14. //请求到ProductsController.cs中的 public HttpResponseMessage PostProduct(Product item) 方法
  15. $("#addItem").click(function () {
  16. var newProduct = Product.create();
  17. newProduct.Name = $("#name").val();
  18. newProduct.Category = $("#category").val();
  19. newProduct.Price = $("#price").val();
  20.  
  21. $.ajax({
  22. url: "/api/Product",
  23. type: "POST",
  24. contentType: "application/json; charset=utf-8",
  25. data: JSON.stringify(newProduct),
  26. success: function () {
  27. alert("添加成功!");
  28. },
  29. error: function (XMLHttpRequest, textStatus, errorThrown) {
  30. alert("请求失败,消息:" + textStatus + " " + errorThrown);
  31. }
  32. });
  33. });
  34.  
  35. //先根据Id查询记录 请求类型:GET 请求url: /api/Products/Id
  36. //请求到ProductsController.cs中的 public Product GetProduct(int id) 方法
  37. $("#showItem").click(function () {
  38. var inputId = $("#id2").val();
  39. $("#name2").val("");
  40. $("#category2").val("");
  41. $("#price2").val("");
  42. $.ajax({
  43. url: "/api/Product/" + inputId,
  44. type: "GET",
  45. contentType: "application/json; charset=urf-8",
  46. success: function (data) {
  47. $("#name2").val(data.Name);
  48. $("#category2").val(data.Category);
  49. $("#price2").val(data.Price);
  50. },
  51. error: function (XMLHttpRequest, textStatus, errorThrown) {
  52. alert("请求失败,消息:" + textStatus + " " + errorThrown);
  53. }
  54. });
  55. });
  56.  
  57. //修改该Id的记录 请求类型:PUT 请求url: /api/Products/Id
  58. //请求到ProductsController.cs中的 public void PutProduct(int id, Product product) 方法
  59. $("#editItem").click(function () {
  60. var inputId = $("#id2").val();
  61. var newProduct = Product.create();
  62. newProduct.Name = $("#name2").val();
  63. newProduct.Category = $("#category2").val();
  64. newProduct.Price = $("#price2").val();
  65.  
  66. $.ajax({
  67. url: "/api/Product/" + inputId,
  68. type: "PUT",
  69. data: JSON.stringify(newProduct),
  70. contentType: "application/json; charset=urf-8",
  71. success: function () {
  72. alert("修改成功! ");
  73. },
  74. error: function (XMLHttpRequest, textStatus, errorThrown) {
  75. alert("请求失败,消息:" + textStatus + " " + errorThrown);
  76. }
  77. });
  78. });
  79.  
  80. //删除输入Id的记录 请求类型:DELETE 请求url: /api/Products/Id
  81. //请求到ProductsController.cs中的 public void DeleteProduct(int id) 方法
  82. $("#removeItem").click(function () {
  83. var inputId = $("#id2").val();
  84. $.ajax({
  85. url: "/api/Product/" + inputId,
  86. type: "DELETE",
  87. contentType: "application/json; charset=uft-8",
  88. success: function (data) {
  89. alert("Id为 " + inputId + " 的记录删除成功!");
  90. },
  91. error: function (XMLHttpRequest, textStatus, errorThrown) {
  92. alert("请求失败,消息:" + textStatus + " " + errorThrown);
  93. }
  94. });
  95. });
  96. </script>

这里,WebApi的一个简单的增删改查项目就完成了,选择执行项目即可测试。注意到,其中用ajax发起请求时,发送到服务器端的数据直接是一个json字符串,当然这个json字符串中每个字段要和Product.cs类中的每个字段同名对应,在服务器端接收数据的时候,我们并没有对接收到的数据进行序列化,而返回数据给客户端的时候也并没有对数据进行反序列化,大大节省了以前开发中不停地进行序列化和反序列化的时间。

Web API开发实例——对产品Product进行增删改查的更多相关文章

  1. 初入码田--ASP.NET MVC4 Web应用开发之二 实现简单的增删改查

    初入码田--ASP.NET MVC4 Web应用之创建一个空白的MVC应用程序 初入码田--ASP.NET MVC4 Web应用开发之一 实现简单的登录 2016-07-29  一.创建M002Adm ...

  2. 基于SpringBoot开发一个Restful服务,实现增删改查功能

    前言 在去年的时候,在各种渠道中略微的了解了SpringBoot,在开发web项目的时候是如何的方便.快捷.但是当时并没有认真的去学习下,毕竟感觉自己在Struts和SpringMVC都用得不太熟练. ...

  3. salesforce 零基础学习(五十一)使用 Salesforce.com SOAP API 实现用户登录以及简单的增删改查(JAVA访问salesforce)

    此篇请参看:https://resources.docs.salesforce.com/202/latest/en-us/sfdc/pdf/salesforce_developer_environme ...

  4. 【共享单车】—— React后台管理系统开发手记:员工管理之增删改查

    前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...

  5. abp vnext 开发快速入门 2 实现基本增删改查

    上篇说了abp vnext 的大体框架结构,本篇说下如何实现基础的增删改查.实现增删改查有以下几个步骤: 1.配置数据库连接 2.领域层(Domain)创建实体,Ef core 层配置Dbset( 用 ...

  6. 使用Java api对HBase 2.4.5进行增删改查

    1.运行hbase 2.新建maven项目 2.将hbase-site.xml放在项目的resources文件夹下 3.修改pom.xml文件,引入hbase相关资源 <repositories ...

  7. C#设计模式总结 C#设计模式(22)——访问者模式(Vistor Pattern) C#设计模式总结 .NET Core launch.json 简介 利用Bootstrap Paginator插件和knockout.js完成分页功能 图片在线裁剪和图片上传总结 循序渐进学.Net Core Web Api开发系列【2】:利用Swagger调试WebApi

    C#设计模式总结 一. 设计原则 使用设计模式的根本原因是适应变化,提高代码复用率,使软件更具有可维护性和可扩展性.并且,在进行设计的时候,也需要遵循以下几个原则:单一职责原则.开放封闭原则.里氏代替 ...

  8. 循序渐进学.Net Core Web Api开发系列【9】:常用的数据库操作

    系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇描述一 ...

  9. 循序渐进学.Net Core Web Api开发系列【8】:访问数据库(基本功能)

    系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇讨论如 ...

随机推荐

  1. jquery选择伪元素属性的方法

    CSS伪元素不是DOM元素,因此你无法直接选择到它们 一个方法是为该元素添加新类,并通过设置新类的属性来达到改变伪元素属性的效果: .checkboxWrapper.selected::before{ ...

  2. 使用 JavaScript 实现链表

    代码: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8 ...

  3. 15.2 THE USE OF A LARGE REGISTER FILE

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION

  4. Win8.1密钥

    Win8.1 在线永久激活密钥一枚!  78BHN-M3KRH-PCP9W-HQJYR-Q9KHD [剩余次数:7K多+] 继续增加 [Key]:HPCJW-VGYW4-CR7W2-JG6Q7-K4Q ...

  5. 安装docker-compose

    下载到合适的位置 curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s` ...

  6. javascript对json对象的序列化与反序列化

    首先引入一个json2.js.官方的地址为:https://github.com/douglascrockford/JSON-js 这里为了方便我直接贴上源代码 /* json2.js 2013-05 ...

  7. Bootstrap 响应式设计

    本教程讲解如何在网页布局中应用响应式设计.在课程中,您将学到响应式 Web 设计.随着移动设备的普及,如何让用户通过移动设备浏览您的网站获得良好的视觉效果,已经是一个不可避免的问题了.响应式 Web ...

  8. 数据库中 关于不能用in 不能用exist 等关键字 查询不出现字段的问题

    这是之前在网上见到的一道题,后来心里略微想了想 觉得应该可能,所以就一闪而过了,之前去面试晨光的时候面试者问了我这道问题,当时也只是把自己的想法说了一下,可能因为当时面试的感觉不太好,面试官也没有追究 ...

  9. JQuery基础二

    1.表单过滤器 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  10. 用mysql++读写二进制

    方法1: // mysqlTest.cpp : 定义控制台应用程序的入口点. #include "stdafx.h" #include <mysql++.h> #inc ...