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)用于接收用户的输入和用户进行直接交互。

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace ProductStore.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace ProductStore.Models
{
interface IProductRepository
{
IEnumerable<Product> GetAll();
Product Get(int id);
Product Add(Product item);
void Remove(int id);
bool Update(Product item);
}
}

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace ProductStore.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;
}
}
}

此时,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控制器类,如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ProductStore.Models;
using System.Web.Http;
using System.Net;
using System.Net.Http; namespace ProductStore.Controllers
{
public class ProductsController : ApiController
{
static readonly IProductRepository repository = new ProductRepository(); //GET: /api/products
public IEnumerable<Product> GetAllProducts()
{
return repository.GetAll();
} //GET: /api/products/id
public Product GetProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
} //GET: /api/products?category=category
public IEnumerable<Product> GetProductsByCategory(string category)
{
return repository.GetAll().Where(p=>string.Equals(p.Category,category,StringComparison.OrdinalIgnoreCase));
} //POST: /api/products
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;
} //PUT: /api/products/id
public void PutProduct(int id, Product product)
{
product.Id = id;
if (!repository.Update(product))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
} //Delete: /api/products/id
public void DeleteProduct(int id)
{
Product item = repository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
repository.Remove(id);
}
}
}

使该类继承于ApiController类,在其中实现处理各种Get,Post,Put,Delete类型Http请求的方法。

每一个方法前都有一句注释,标识了该方法的针对的请求的类型(取决于方法的开头),以及要请求到该方法,需要使用的url。

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

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

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

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

<div id="body">
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<section >
  <h2>添加记录</h2>
  Name:<input id="name" type="text" /><br />
  Category:<input id="category" type="text" />
  Price:<input id="price" type="text" /><br />
  <input id="addItem" type="button" value="添加" />
</section> <section>
<br />
<br />
  <h2>修改记录</h2>
  Id:<input id="id2" type="text" /><br />
  Name:<input id="name2" type="text" /><br />
  Category:<input id="category2" type="text" />
  Price:<input id="price2" type="text" /><br />
  <input id="showItem" type="button" value="查询" />
  <input id="editItem" type="button" value="修改" />
  <input id="removeItem" type="button" value="删除" />
</section> </div>

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

  <script>
//用于保存用户输入数据
var Product = {
create: function () {
Id: "";
Name: "";
Category: "";
Price: "";
return Product;
}
} //添加一条记录 请求类型:POST 请求url: /api/Products
//请求到ProductsController.cs中的 public HttpResponseMessage PostProduct(Product item) 方法
$("#addItem").click(function () {
var newProduct = Product.create();
newProduct.Name = $("#name").val();
newProduct.Category = $("#category").val();
newProduct.Price = $("#price").val(); $.ajax({
url: "/api/Products",
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(newProduct),
success: function () {
alert("添加成功!");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("请求失败,消息:" + textStatus + " " + errorThrown);
}
});
}); //先根据Id查询记录 请求类型:GET 请求url: /api/Products/Id
//请求到ProductsController.cs中的 public Product GetProduct(int id) 方法
$("#showItem").click(function () {
var inputId = $("#id2").val();
$("#name2").val("");
$("#category2").val("");
$("#price2").val("");
$.ajax({
url: "/api/Products/" + inputId,
type: "GET",
contentType: "application/json; charset=urf-8",
success: function (data) {
$("#name2").val(data.Name);
$("#category2").val(data.Category);
$("#price2").val(data.Price);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("请求失败,消息:" + textStatus + " " + errorThrown);
}
});
}); //修改该Id的记录 请求类型:PUT 请求url: /api/Products/Id
//请求到ProductsController.cs中的 public void PutProduct(int id, Product product) 方法
$("#editItem").click(function () {
var inputId = $("#id2").val();
var newProduct = Product.create();
newProduct.Name = $("#name2").val();
newProduct.Category = $("#category2").val();
newProduct.Price = $("#price2").val(); $.ajax({
url: "/api/Products/" + inputId,
type: "PUT",
data: JSON.stringify(newProduct),
contentType: "application/json; charset=urf-8",
success: function () {
alert("修改成功! ");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("请求失败,消息:" + textStatus + " " + errorThrown);
}
});
}); //删除输入Id的记录 请求类型:DELETE 请求url: /api/Products/Id
//请求到ProductsController.cs中的 public void DeleteProduct(int id) 方法
$("#removeItem").click(function () {
var inputId = $("#id2").val();
$.ajax({
url: "/api/Products/" + inputId,
type: "DELETE",
contentType: "application/json; charset=uft-8",
success: function (data) {
alert("Id为 " + inputId + " 的记录删除成功!");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("请求失败,消息:" + textStatus + " " + errorThrown);
}
});
});
</script>

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

webApi实现增删改查操作的更多相关文章

  1. 【OF框架】新建库表及对应实体,并实现简单的增删改查操作,封装操作标准WebApi

    准备 搭建好项目框架及数据库,了解框架规范. 1.数据库表和实体一一对应,表名实体名名字相同,用小写,下划线连接.字段名用驼峰命名法,首字母大写. 2.实体放在Entities目录下,继承Entity ...

  2. mongoVUE的增删改查操作使用说明

    mongoVUE的增删改查操作使用说明 一. 查询 1. 精确查询 1)右键点击集合名,再左键点击Find 或者直接点击工具栏上的Find 2)查询界面,包括四个区域 {Find}区,查询条件格式{& ...

  3. (转)SQLite数据库增删改查操作

    原文:http://www.cnblogs.com/linjiqin/archive/2011/05/26/2059182.html SQLite数据库增删改查操作 一.使用嵌入式关系型SQLite数 ...

  4. 详谈easyui datagrid增删改查操作

    转自:http://blog.csdn.net/abauch_d/article/details/7734395 前几天我把easyui dadtagrid的增删改查的实现代码贴了出来,发现访问量达到 ...

  5. PHP程序中使用PDO对象实现对数据库的增删改查操作的示例代码

    PHP程序中使用PDO对象实现对数据库的增删改查操作(PHP+smarty) dbconn.php <?php //------------------------使用PDO方式连接数据库文件- ...

  6. 浅谈dataGridView使用,以及画面布局使用属性,对datagridview进行增删改查操作,以及委托使用技巧

        通过几天的努力后,对datagridview使用作一些简要的介绍,该实例主要运用与通过对datagridview操作.对数据进行增删改查操作时,进行逻辑判断执行相关操作.简单的使用委托功能,实 ...

  7. 05_Elasticsearch 单模式下API的增删改查操作

    05_Elasticsearch 单模式下API的增删改查操作 安装marvel 插件: zjtest7-redis:/usr/local/elasticsearch-2.3.4# bin/plugi ...

  8. JDBC连接数据库及增删改查操作

    什么是JDBC?Java语言访问数据库的一种规范,是一套APIJDBC (Java Database Connectivity) API,即Java数据库编程接口,是一组标准的Java语言中的接口和类 ...

  9. Elasticsearch 单模式下API的增删改查操作

    <pre name="code" class="html">Elasticsearch 单模式下API的增删改查操作 http://192.168. ...

随机推荐

  1. cocos2d_x_08_游戏_FlappyBird

    终于效果图: 环境版本号:cocos2d-x-3.3beta0 使用内置的物理引擎 计时器没有加入,可參考[cocos2d_x_06_游戏_一个都不能死] 主场景 // // FlappyBirdSc ...

  2. android.annotation cannot be resolved

    http://stackoverflow.com/questions/14870596/android-annotation-cannot-be-resolved As Artem suggested ...

  3. [VirtualBox] Install Ubuntu 14.10 error 5 Input/output error

    After you download the VirtualBox install package and install it (just defualt setting). Then you sh ...

  4. Linux性能优化--CPU[备忘]

    http://kumu-linux.github.io/blog/2014/04/21/performance-cpu/

  5. java_客户端防表单重复提交和服务器端session防表单重复提交

    用户输入FormServlet链接 FormServlet-〉form.jsp->DoFormServlet FormServlet:产生token,放在session中 form.jsp:hi ...

  6. codereview介绍

    1. 定义: Code review is systematic examination (often known as peer review) of computer source code. I ...

  7. 常用免费快递查询API对接案例

    现在许多电商公司和ERP都会寻找比较适用的集成快递查询接口,减少对接难度,现在整理一下常用的免费快递查询接口,并附上调用案例,如果有觉得不对的地方,望能够一起沟通探讨! 一.快递查询接口 目前有提供免 ...

  8. Android_CntextMenu_example_textSize

    menu.xml <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item ...

  9. C++第四章循环

    学习时候的点: 1.用户来控制是否继续进行的模板: char goonLoop=’y’; while(goonLoop==’y’){ //logic cout<<”输入y 来继续当前逻辑, ...

  10. 输入参数varargin

    一种特别的输入参数varargin 可以在自定义函数中得到,这种函数支持输入参数的变量的个数.这个参数显在输入参数列表的最后一项,它返回一个单元阵列,所以一个输入实参可以包括任意数目的实参.每一个实参 ...