MVC中使用Web API和EntityFramework
在ASP.NET MVC中使用Web API和EntityFramework构建应用程序
最近做了一个项目技术预研:在ASP.NET MVC框架中使用Web API和EntityFramework,构建一个基础的架构,并在此基础上实现基本的CRUD应用。
以下是详细的步骤。
第一步
在数据库中创建一张数据表,表名为Customer,见下图:

第二步
打开 Visual Studio,新建项目。
选择'ASP.NET Web Application',命名为'WebApi'。

我们要创建一个'Web API',在模板中选择'Web API',点击'确定'。

第三步
接下来我要添加一个类。
右键点击这个 web api项目,添加一个'ADO.NET Entity Data Model'。

添加'EF Designer from database',点击'下一步'。

在配置窗口中添加新连接,输入服务器名称,选择数据库,点击'确定'。

点击'下一步',选择要关联的数据表。

点击'完成'。
第四步
现在的工作就是要为Wep Api添加控制器了。
右键选择'controllers'文件夹。

选择'MVC5 Controller with views, using Entity Framework'。

点击'添加'。
选择数据模型类Customer,选择Data context类文件,本例中为SystemTestEntity。
设置控制器名称为CustomersController,点击'添加'。

上述操作完成后,CustomerController.cs会自动生成。
CustomerController.cs
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.Http.Description;
using CRUDWebApiExam.Models;
namespace CRUDWebApiExam.Controllers
{
public class CustomersController : ApiController
{
private SystemTestEntities db = new SystemTestEntities();
// GET: api/Customers
public IQueryable<Customer> GetCustomer()
{
return db.Customer;
}
// GET: api/Customers/5
[ResponseType(typeof(Customer))]
public IHttpActionResult GetCustomer(int id)
{
Customer customer = db.Customer.Find(id);
if (customer == null)
{
return NotFound();
}
return Ok(customer);
}
// PUT: api/Customers/5
[ResponseType(typeof(void))]
public IHttpActionResult PutCustomer(int id, Customer customer)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != customer.CustomerId)
{
return BadRequest();
}
db.Entry(customer).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!CustomerExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/Customers
[ResponseType(typeof(Customer))]
public IHttpActionResult PostCustomer(Customer customer)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Customer.Add(customer);
db.SaveChanges();
return CreatedAtRoute("DefaultApi", new { id = customer.CustomerId }, customer);
}
// DELETE: api/Customers/5
[ResponseType(typeof(Customer))]
public IHttpActionResult DeleteCustomer(int id)
{
Customer customer = db.Customer.Find(id);
if (customer == null)
{
return NotFound();
}
db.Customer.Remove(customer);
db.SaveChanges();
return Ok(customer);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool CustomerExists(int id)
{
return db.Customer.Count(e => e.CustomerId == id) > 0;
}
}
}
运行这个 Web Api项目,你会看到下面的结果
第五步
到此为止,web api已经构建成功了。接下来我们需要为这个web api服务添加消费对象了,这个消费对象就是本文要涉及的MVC项目。
- 首先要添加一个model类,我们可以直接采用上文中的Customer类。右键点击models文件夹,添加类并命名。本例中,我直接命名为Customer.cs。
Customer.cs
using System;
using System.ComponentModel.DataAnnotations;
namespace MVCPersatantion.Models
{
public class Customer
{
[Display(Name = "CustomerId")]
public int CustomerId { get; set; }
[Display(Name = "Name")]
public string Name { get; set; }
[Display(Name = "Address")]
public string Address { get; set; }
[Display(Name = "MobileNo")]
public string MobileNo { get; set; }
[Display(Name = "Birthdate")]
[DataType(DataType.Date)]
public DateTime Birthdate { get; set; }
[Display(Name = "EmailId")]
public string EmailId { get; set; }
}
}
- customer类添加完成后,接下来需要添加一个ViewModel文件夹,并在里面新建一个CustomerViewModel.cs文件。
CustomerViewModel.cs
using MVCPersatantion.Models;
namespace MVCPersatantion.ViewModel
{
public class CustomerViewModel
{
public Customer customer { get; set; }
}
}
第六步
我已经添加了一个消费web api服务的类,现在我还需要添加一个Client类。
- 右键点击models文件夹,添加类文件CustomerClient.cs。
CustomerClient.cs
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
namespace MVCPersatantion.Models
{
public class CustomerClient
{
private string Base_URL = "http://localhost:30110/api/";
public IEnumerable<Customer> findAll()
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(Base_URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("customers").Result;
if (response.IsSuccessStatusCode)
return response.Content.ReadAsAsync<IEnumerable<Customer>>().Result;
return null;
}
catch
{
return null;
}
}
public Customer find(int id)
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(Base_URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync("customers/" + id).Result;
if (response.IsSuccessStatusCode)
return response.Content.ReadAsAsync<Customer>().Result;
return null;
}
catch
{
return null;
}
}
public bool Create(Customer customer)
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(Base_URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.PostAsJsonAsync("customers", customer).Result;
return response.IsSuccessStatusCode;
}
catch
{
return false;
}
}
public bool Edit(Customer customer)
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(Base_URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.PutAsJsonAsync("customers/" + customer.CustomerId, customer).Result;
return response.IsSuccessStatusCode;
}
catch
{
return false;
}
}
public bool Delete(int id)
{
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(Base_URL);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.DeleteAsync("customers/" + id).Result;
return response.IsSuccessStatusCode;
}
catch
{
return false;
}
}
}
}
细心的朋友们可能已经发现,我的代码中有一些重复代码。实际应用中我们可以抽取成公用代码,这样任何地方都能够使用了。这里为了清楚的阐述过程,所以写了一些重复的代码。
我们看第一行private string Base_URL = "http://localhost:50985/api/",这个Base_URL是web api的服务地址。
接下来就可以编写Insert、Update、Delete、Select的业务逻辑了。
第七步
右键点击Controllers文件夹,添加一个名为Customer控制器,控制器中添加服务客户端调用的方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCPersatantion.Models;
using MVCPersatantion.ViewModel;
namespace MVCPersatantion.Controllers
{
public class CustomerController : Controller
{
// GET: Customer
public ActionResult Index()
{
CustomerClient CC = new CustomerClient();
ViewBag.listCustomers = CC.findAll();
return View();
}
[HttpGet]
public ActionResult Create()
{
return View("Create");
}
[HttpPost]
public ActionResult Create(CustomerViewModel cvm)
{
CustomerClient CC = new CustomerClient();
CC.Create(cvm.customer);
return RedirectToAction("Index");
}
public ActionResult Delete(int id)
{
CustomerClient CC = new CustomerClient();
CC.Delete(id);
return RedirectToAction("Index");
}
[HttpGet]
public ActionResult Edit(int id)
{
CustomerClient CC = new CustomerClient();
CustomerViewModel CVM = new CustomerViewModel();
CVM.customer = CC.find(id);
return View("Edit",CVM);
}
[HttpPost]
public ActionResult Edit(CustomerViewModel CVM)
{
CustomerClient CC = new CustomerClient();
CC.Edit(CVM.customer);
return RedirectToAction("Index");
}
}
}
第八步
创建视图页面Index.cshtml。
在Index页面中添加代码。
Index.cshtml
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div align="center">
@Html.ActionLink("Create", "Create", "Customer", new { area = "" }, null)
<br /><br />
<table cellpadding="2"
class="table"
cellspacing="2"
border="1">
<tr class="btn-primary">
<th>
CustomerId
</th>
<th> Name</th>
<th> Address</th>
<th> MobileNo</th>
<th> Birthdate</th>
<th> EmailId</th>
<th> Action</th>
</tr>
@foreach (var Cust in ViewBag.listCustomers)
{
<tr class="btn-success">
<td>
@Cust.CustomerId
</td>
<td>
@Cust.Name
</td>
<td>
@Cust.Address
</td>
<td>
@Cust.MobileNo
</td>
<td>
@Cust.Birthdate.ToString("dd/MM/yyyy")
</td>
<td>
@Cust.EmailId
</td>
<td>
<a onclick="return confirm('确定要删除这条数据?')"
href="@Url.Action("Delete","Customer",new {id= Cust.CustomerId})">Delete</a> ||
<a href="@Url.Action("Edit","Customer",new {id= Cust.CustomerId})">Edit</a>
@*@Html.ActionLink("Edit", "Edit", "Customer", new { id = Cust.CustomerId })*@
</td>
</tr>
}
</table>
</div>
添加新增数据模块Create。
在Customer控制器中添加create方法,在view中增加Create.cshtml。
Create.cshtml
@model WebApiMVC.ViewModel.CustomerViewModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<div align = "center" >
@using (Html.BeginForm("create", "Customer", FormMethod.Post))
{
<table class="table">
<tr>
<td>
@Html.LabelFor(model => model.customer.Name)
</td>
<td>
@Html.TextBoxFor(model => model.customer.Name)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.customer.Address)
</td>
<td>
@Html.TextBoxFor(model => model.customer.Address)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.customer.MobileNo)
</td>
<td>
@Html.TextBoxFor(model => model.customer.MobileNo)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.customer.Birthdate)
</td>
<td>
@Html.TextBoxFor(model => model.customer.Birthdate)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.customer.EmailId)
</td>
<td>
@Html.TextBoxFor(model => model.customer.EmailId)
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="保存" />
</td>
</tr>
</table>
}
</div>
添加修改数据模块Edit。
在Customer控制器中添加edit方法,在view中增加Edit.cshtml。
Edit.cshtml
@{
ViewBag.Title = "Edit";
}
@model WebApiMVC.ViewModel.CustomerViewModel
<h2> Edit </h2>
<div align="center" width="500px">
@using (Html.BeginForm("Edit", "Customer", FormMethod.Post))
{
<table class="table"
width="400px"
cellpadding="20">
<tr class="btn-default">
<td>
@Html.LabelFor(model => model.customer.Name)
</td>
<td>
@Html.TextBoxFor(model => model.customer.Name)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.customer.Address)
</td>
<td>
@Html.TextBoxFor(model => model.customer.Address)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.customer.MobileNo)
</td>
<td>
@Html.TextBoxFor(model => model.customer.MobileNo)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.customer.Birthdate)
</td>
<td>
@Html.TextBoxFor(model => model.customer.Birthdate)
</td>
</tr>
<tr>
<td>
@Html.LabelFor(model => model.customer.EmailId)
</td>
<td>
@Html.TextBoxFor(model => model.customer.EmailId)
</td>
</tr>
<tr>
<td> </td>
<td>
<input type="submit" value="保存" /> <a class="btn-primary" href="@Url.Action("Index ","Customer ")"> 返回 </a>
@Html.HiddenFor(model => model.customer.CustomerId)
</td>
</tr>
</table>
}
</div>
最终项目代码已经完成了。这时候我们运行项目试试看了。但还有一点要注意的是,我们必须同时运行web api和mvc项目。怎么办呢?其实只要在项目属性里设置就可以了。
- 右键解决方案,选择属性(Properties)。

接来下在启动项目选项中,选择
多项目启动,在Action中设置两个项目同时启动。运行项目,看看CRUD操作的执行结果。
Select
Insert
Update
Delete
这是整个技术预研的过程,本文末尾位置提供代码下载。
MVC中使用Web API和EntityFramework的更多相关文章
- 在ASP.NET MVC中使用Web API和EntityFramework构建应用程序
最近做了一个项目技术预研:在ASP.NET MVC框架中使用Web API和EntityFramework,构建一个基础的架构,并在此基础上实现基本的CRUD应用. 以下是详细的步骤. 第一步 在数据 ...
- ASP.NET Core MVC中构建Web API
在ASP.NET CORE MVC中,Web API是其中一个功能子集,可以直接使用MVC的特性及路由等功能. 在成功构建 ASP.NET CORE MVC项目之后,选中解决方案,先填加一个API的文 ...
- [译]ABP框架使用AngularJs,ASP.NET MVC,Web API和EntityFramework构建N层架构的SPA应用程序
本文转自:http://www.skcode.cn/archives/281 本文演示ABP框架如何使用AngularJs,ASP.NET MVC,Web API 和EntityFramework构建 ...
- ABP 教程文档 1-1 手把手引进门之 AngularJs, ASP.NET MVC, Web API 和 EntityFramework(官方教程翻译版 版本3.2.5)含学习资料
本文是ABP官方文档翻译版,翻译基于 3.2.5 版本 转载请注明出处:http://www.cnblogs.com/yabu007/ 谢谢 官方文档分四部分 一. 教程文档 二.ABP 框架 三. ...
- ABP示例程序-使用AngularJs,ASP.NET MVC,Web API和EntityFramework创建N层的单页面Web应用
本片文章翻译自ABP在CodeProject上的一个简单示例程序,网站上的程序是用ABP之前的版本创建的,模板创建界面及工程文档有所改变,本文基于最新的模板创建.通过这个简单的示例可以对ABP有个更深 ...
- 返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, .net 4.5 带来的更方便的异步操作
原文:返璞归真 asp.net mvc (11) - asp.net mvc 4.0 新特性之自宿主 Web API, 在 WebForm 中提供 Web API, 通过 Web API 上传文件, ...
- Mvc 6 中创建 Web Api
如何在Mvc 6 中创建 Web Api以及如何脱离IIS实现自我托管 微软推出的Asp.net vNext(asp.net 5.0)的其中的一个目标就是统一mvc 和web api 的框架.接下来我 ...
- ASP.NET 5系列教程 (六): 在 MVC6 中创建 Web API
ASP.NET 5.0 的主要目标之一是统一MVC 和 Web API 框架应用. 接下来几篇文章中您会了解以下内容: ASP.NET MVC 6 中创建简单的web API. 如何从空的项目模板中启 ...
- ASP.NET MVC4中调用WEB API的四个方法
http://tech.it168.com/a2012/0606/1357/000001357231_all.shtml [IT168技术]当今的软件开发中,设计软件的服务并将其通过网络对外发布,让各 ...
随机推荐
- Vasya and Multisets CodeForces - 1051C(英语限制了我的想象力)
题意: 对输入的每个数都进行分配到两个多重集中,问分配完以后 每个多重集中的个数为1的元素是否相等 相等则输出一个分配方式, 不想等为NO 解析: 三种情况 1.原数列中个数为1 的数的个数为偶数 ...
- Pathwalks CodeForces - 960F(主席树 || 树状数组)
题意: 求树上最长上升路径 解析: 树状数组版: 998ms edge[u][w] 代表以u为一条路的终点的小于w的最长路径的路的条数 · 那么edge[v][w] = max(edge[u][w-1 ...
- 自定义Kettle数据库插件
项目需要实现使用Kettle向神通数据库中写入数据,Kettle官方标准的数据库插件里面并没有对神通数据库的支持,因此需要自己写一个数据库插件.下面我们开始写一个数据库插件 1.在eclipse中创建 ...
- 洛谷P3928 Sequence2(dp,线段树)
题目链接: 洛谷 题目大意在描述底下有.此处不赘述. 明显是个类似于LIS的dp. 令 $dp[i][j]$ 表示: $j=1$ 时表示已经处理了 $i$ 个数,上一个选的数来自序列 $A[0]$ 的 ...
- POJ 2251 Dungeon Master /UVA 532 Dungeon Master / ZOJ 1940 Dungeon Master(广度优先搜索)
POJ 2251 Dungeon Master /UVA 532 Dungeon Master / ZOJ 1940 Dungeon Master(广度优先搜索) Description You ar ...
- c++并发编程之线程的互斥与同步
什么是线程的同步与互斥? 互斥:指在某一时刻指允许一个进程运行其中的程序片,具有排他性和唯一性. 对于线程A和线程B来讲,在同一时刻,只允许一个线程对临界资源进行操作,即当A进入临界区对资源操作时,B ...
- sking
#include #include #include typedef struct SKI{ int data; int x; int y; char flag; int len; }STSKI; i ...
- Chart Controls 简介与下载
虽然博客园已有人介绍过了,还是忍不住介绍一下微软这套免费又功能强大的图表控件「Microsoft Chart Controls for Microsoft .NET Framework 3.5」.本帖 ...
- 深度学习 vs. 概率图模型 vs. 逻辑学
深度学习 vs. 概率图模型 vs. 逻辑学 摘要:本文回顾过去50年人工智能(AI)领域形成的三大范式:逻辑学.概率方法和深度学习.文章按时间顺序展开,先回顾逻辑学和概率图方法,然后就人工智能和机器 ...
- sh脚本学习之: 命令处理
输出 默认是命令行输出 > 替换输出 >> append输出 2> 错误输出 < 由文件输入 <<eof 控制台输入,eof为输入结束标志 /dev/nul ...