ASP.NET Web API实践系列02,在MVC4下的一个实例, 包含EF Code First,依赖注入, Bootstrap等
本篇体验在MVC4下,实现一个对Book信息的管理,包括增删查等,用到了EF Code First, 使用Unity进行依赖注入,前端使用Bootstrap美化。先上最终效果:

→创建一个MVC4项目,选择Web API模版。

→在Models文件夹创建一个Book.cs类。
namespace MyMvcAndWebApi.Models{public class Book{public int Id { get; set; }public string Name { get; set; }public decimal Price { get; set; }}}
→在Models文件夹创建BookInitializer类,用来初始化数据库表数据。
using System.Data.Entity;namespace MyMvcAndWebApi.Models{public class BookInitializer : DropCreateDatabaseIfModelChanges<BookStore>{protected override void Seed(BookStore context){context.Books.Add(new Book() {Name = "我有一头小毛驴", Price = 200M});context.Books.Add(new Book() { Name = "今天天气真好", Price = 300M });context.Books.Add(new Book() { Name = "秋天是落叶的季节", Price = 500M });}}}
→在Models文件夹中,创建BookStore类,派生于DbContext。
using System.Data.Entity;namespace MyMvcAndWebApi.Models{public class BookStore : DbContext{public BookStore() : base("conn"){Database.SetInitializer(new BookInitializer());}public DbSet<Book> Books { get; set; }}}
→在Web.config中配置连接字符串。
<connectionStrings>......<add name="conn" connectionString="Data Source=.;User=yourusername;Password=yourpassword;Initial Catalog=BookStore;Integrated Security=True" providerName="System.Data.SqlClient" /></connectionStrings>
→Repository首先需要一个接口,在Models文件夹中创建IBookRepository接口。
using System.Collections.Generic;namespace MyMvcAndWebApi.Models{public interface IBookRepository{IEnumerable<Book> GetAll();Book Get(int id);Book Add(Book book);void Remove(int id);bool Update(Book book);}}
→实现IBookRepository接口,用到BookStore这个上下文。
using System.Collections.Generic;using System.Data;namespace MyMvcAndWebApi.Models{public class BookRepository : IBookRepository{private BookStore db = new BookStore();public BookRepository(){}public IEnumerable<Book> GetAll(){return db.Books;}public Book Add(Book book){db.Books.Add(book);db.SaveChanges();return book;}public void Remove(int id){Book book = db.Books.Find(id);db.Books.Remove(book);db.SaveChanges();}public bool Update(Book book){db.Entry(book).State = EntityState.Modified;db.SaveChanges();return true;}public Book Get(int id){return db.Books.Find(id);}}}
→有了接口和实现,接下来会用到依赖注入。选择使用Unity,在NuGet中下载。
→首先需要一个依赖注入容器。在项目下创建Helper文件夹,在其中创建IoCContainer类。
using System;using System.Collections.Generic;using System.Web.Http.Dependencies;using Microsoft.Practices.Unity;namespace MyMvcAndWebApi.Helper{class ScopeContainer : IDependencyScope{protected IUnityContainer container;public ScopeContainer(IUnityContainer container){if (container == null){throw new ArgumentNullException("container");}this.container = container;}public object GetService(Type serviceType){if (container.IsRegistered(serviceType)){return container.Resolve(serviceType);}else{return null;}}public IEnumerable<object> GetServices(Type serviceType){if (container.IsRegistered(serviceType)){return container.ResolveAll(serviceType);}else{return new List<object>();}}public void Dispose(){container.Dispose();}}class IoCContainer : ScopeContainer, IDependencyResolver{public IoCContainer(IUnityContainer container): base(container){}public IDependencyScope BeginScope(){var child = container.CreateChildContainer();return new ScopeContainer(child);}}}
→在Global.asax中注册Unity。
sing System.Web.Http;using System.Web.Mvc;using System.Web.Optimization;using System.Web.Routing;using Microsoft.Practices.Unity;using MyMvcAndWebApi.Controllers;using MyMvcAndWebApi.Helper;using MyMvcAndWebApi.Models;namespace MyMvcAndWebApi{// 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,// 请访问 http://go.microsoft.com/?LinkId=9394801public class WebApiApplication : System.Web.HttpApplication{//注册控制器,接口和实现void ConfigureApi(HttpConfiguration config){var unity = new UnityContainer();unity.RegisterType<BooksController>();unity.RegisterType<IBookRepository, BookRepository>(new HierarchicalLifetimeManager());config.DependencyResolver = new IoCContainer(unity);}protected void Application_Start(){AreaRegistration.RegisterAllAreas();//注册依赖注入ConfigureApi(GlobalConfiguration.Configuration);WebApiConfig.Register(GlobalConfiguration.Configuration);FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);}}}
→创建一个空的Api控制器,编写如下:
using System;using System.Collections.Generic;using System.Net;using System.Net.Http;using System.Web.Http;using MyMvcAndWebApi.Models;namespace MyMvcAndWebApi.Controllers{public class BooksController : ApiController{//_repository运行时变量,在首次引用IBookRepository方法时动态分配内存private static IBookRepository _repository;public BooksController(IBookRepository repository){if (repository == null){throw new ArgumentNullException("repository");}_repository = repository;}//根据惯例,如果action名称以Get开头,那就接收Get请求public IEnumerable<Book> GetAllBooks(){return _repository.GetAll();}//ASP.NET Web API会自动帮我们把URL中的字符串id转换成参数类型intpublic Book GetBook(int id){Book book = _repository.Get(id);if (book == null){//HttpResponseException封装返回的异常//HttpResponseMessage封装返回的信息throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));}return book;}//添加//action名以post开头,按照惯例,接收post请求//客户端发送来序列化的Book对象,在服务端对Book对象反序列化public HttpResponseMessage PostBook(Book book){book = _repository.Add(book);// Web API默认返回的状态码为200,可是,根据HTTP/1.1协议,在添加完,我们希望返回201状态码var response = Request.CreateResponse(HttpStatusCode.Created, book);//返回新创建资源的urlstring uri = Url.Route(null, new {id = book.Id});response.Headers.Location = new Uri(Request.RequestUri, uri);return response;}//修改//参数id从url中获取,book从request中反序列化//根据惯例,Put开头的action,接收put请求public void PutBook(int id, Book book){book.Id = id;if (!_repository.Update(book)){throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));}}//删除//根据管理,Delete开头接收delete请求public HttpResponseMessage DeleteBook(int id){_repository.Remove(id);//返回200状态码表示删除成功//返回202状态码表示正在删除//返回204状态码表示没有内容return new HttpResponseMessage(HttpStatusCode.NoContent);}}}
以上,所有action方法名称都符合了惯例。
→修改Home/Index.cshtml,我们在此使用jquery与服务端api控制器进行交互。
@section scripts {<script src="@Url.Content("~/Scripts/jquery-1.6.2.js")" type="text/javascript"> </script><script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"> </script><script src="@Url.Content("~/Scripts/jQuery.tmpl.js")" type="text/javascript"> </script><script type="text/javascript">$(function () {//Get请求$.getJSON("api/books",function (data) {$.each(data,function (index, value) {$("#bookTemplate").tmpl(value).appendTo("#books");});$("#loader").hide("slow");$("#addBook").show("slow");});//添加$("#addBook").submit(function () {$.post("api/books",$("#addBook").serialize(), //序列化Book对象function (value) {$("#bookTemplate").tmpl(value).appendTo("#books");$("#name").val("");$("#price").val("");},"json");return false;});//删除$(".removeBook").live("click", function () {$.ajax({type: "DELETE",url: $(this).attr("href"),context: this,success: function () {$(this).closest("li").remove();}});return false;});$("input[type=\"submit\"], .removeBook, .viewImage").button();});//根据id搜索function find() {var id = $('#bookId').val();$.getJSON("api/books/" + id,function (data) {var str = data.Name + ': $' + data.Price;$('#book').html(str);}).fail(function (jqXHR, textStatus, err) {$('#book').html('Error: ' + err);});}</script><script id="bookTemplate" type="text/html"><li><p><strong> Book ID:</strong> ${ Id}<br /><strong> Book Name:</strong> ${ Name }<br /><strong> Price: $</strong> ${ Price }</p><p><a href="${ Self }" class="button small red removeBook">移除</a></p></li></script>}<body><form method="post" id="addBook"><div class="container_16"><h1 class="title-01">Book信息</h1></div><div class="container_16"><div class="grid_16 body-container"><div class="margin grid_6 alpha"><label for="Name">Name</label><br /><input type="text" id="name" name="Name" class="text grid_4" /><br class="clear" /><label for="Price">Price</label><br /><input type="text" id="price" name="Price" class="text grid_4" /><br class="clear" /><input type="submit" value="添加" class="button small green" /><br /><br /><br class="clear" /><strong id="book">@* <label id="book"></label>*@ </strong><br /><br class="clear" /><br /><label for="bookId">根据ID搜索</label><br /><input type="text" id="bookId" size="20" class="text grid_4" /><br class="clear" /><input type="button" value="搜索" onclick="find();" class="button small gray" /></div><div class="grid_8 omega"><img id="loader" src="data:images/ajax-loader.gif" /><ul id="books" class="books"></ul></div></div></div><br class="clear" /><div class="footer clearfix"></div></form></body>
另外,有关Bootsrap的样式在BundleConfig类中定义。
参考资料:http://www.codeproject.com/Articles/344078/ASP-NET-WebAPI-Getting-Started-with-MVC-and-WebAP
ASP.NET Web API实践系列02,在MVC4下的一个实例, 包含EF Code First,依赖注入, Bootstrap等的更多相关文章
- ASP.NET Web API实践系列05,消息处理管道
ASP.NET Web API的消息处理管道可以理解为请求到达Controller之前.Controller返回响应之后的处理机制.之所以需要了解消息处理管道,是因为我们可以借助它来实现对请求和响应的 ...
- ASP.NET Web API实践系列04,通过Route等特性设置路由
ASP.NET Web API路由,简单来说,就是把客户端请求映射到对应的Action上的过程.在"ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置"一 ...
- ASP.NET Web API实践系列07,获取数据, 使用Ninject实现依赖倒置,使用Knockout实现页面元素和视图模型的双向绑定
本篇接着上一篇"ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API",尝试获取数据. 在Models文件夹下创 ...
- ASP.NET Web API实践系列09,在Fiddler和控制台中模拟GET和POST请求
ASP.NET Web API本质是由一个进程托管的一组类,需要宿主,这个宿主可以是ASP.NET应用程序,可以是MVC项目,可以是控制台应用程序,也可以是自己定制的宿主. 在VS2012中创建一个& ...
- ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API
本篇尝试在现有的ASP.NET MVC 4 项目上增加使用ASP.NET Web API. 新建项目,选择"ASP.NET MVC 4 Web应用程序". 选择"基本&q ...
- ASP.NET Web API实践系列03,路由模版, 路由惯例, 路由设置
ASP.NET Web API的路由和ASP.NET MVC相似,也是把路由放在RouteTable中的.可以在App_Start文件夹中的WebApiConfig.cs中设置路由模版.默认的路由模版 ...
- ASP.NET Web API实践系列01,以ASP.NET Web Form方式寄宿
创建一个空的ASP.NET Web Form项目. 右键项目,添加新项,创建Web API控制器类,TestController. 删除掉TestController默认的内容,编写如下: using ...
- ASP.NET Web API实践系列11,如何设计出优秀的API
本篇摘自:InfoQ的微信公众号 在设计API的时候考虑的问题包括:API所使用的传输协议.支持的消息格式.接口的控制.名称.关联.次序,等等.我们很难始终作出正确的决策,很可能是在多次犯错之后,并从 ...
- ASP.NET Web API 2系列(三):查看WebAPI接口的详细说明及测试接口
引言 前边两篇博客介绍了Web API的基本框架以及路由配置,这篇博客主要解决在前后端分离项目中,为前端人员提供详细接口说明的问题,主要是通过修改WebApi HelpPage相关代码和添加WebAp ...
随机推荐
- PhpStorm,Pycharm,Goland破解
phpstorm是一个轻量级且便捷的PHP IDE,其旨在提供用户效率,可深刻理解用户的编码,提供智能代码补全,快速导航以及即时错误检查.不但是php开发的利器,前端开发也是毫不逊色的.下面记录Php ...
- pyqt5-组件
组件(widgets)是构建一个应用的基础模块.PyQt5有广泛的各式各样的组件,包含:复选按钮(QCheckBox),切换按钮(ToggleButton),滑块条(QSlider),进度条(Prog ...
- Centos7下yum安装zabbix-server的部署(一)
一.环境准备 OS:CentOS 7.2 64bit Zabbix版本:3.0.12 MySQL版本:5.6 hostname ip 主机用途zabbix-server 10.0.0.44 服务端 z ...
- PHP编辑器分享
Sublime 1 .安装了追踪插件,ctrl+鼠标左键点击PHP函数跳到函数声明的位置. 2.已汉化 链接:http://pan.baidu.com/s/1hs5qonE 密码:b8fw 相关文章: ...
- SpringBoot的搭建
一:搭建 1.环境要求 Java7及以上 Spring Framework4.1.5及以上 2.新建一个maven工程 3.pom.xml(生成) <!-- 必须引入spring-parent, ...
- 最受欢迎编程语言又是谁?C语言居首,大数据赢了
C语言占据榜首,但大数据类是最大赢家. IEEE Spectrum的第三次“最受欢迎编程语言”交互式排行榜新鲜出炉.因为不可能顾及到每一个程序员的想法,Spectrum使用多样化.可交互的的指标权重来 ...
- Windows下CRF++进行中文人名识别的初次尝试
语料来自1998年1月份人民日报语料 1 语料处理 1.1 原始语料数据格式 语料中,句子已经被分词好,并且在人名后以“/”标注了“nr”表示是人名,其他非人名的分词没有进行标注 1.2 CRF++要 ...
- 洛谷P2894 [USACO08FEB]酒店Hotel [线段树]
题目传送门 酒店 题目描述 The cows are journeying north to Thunder Bay in Canada to gain cultural enrichment and ...
- 关于ImportError: libssl.so.10: cannot open shared object file: No such file or directory unable to load app 0 (mountpoint='') (callable not found or import error)
一.问题描述 在亚马逊云服务器使用Nginx+uwsgi部署django项目时,项目可以使用python manage.py runserver正常运行,uwsgi测试也没问题,Nginx也正常启动, ...
- Python 项目实践三(Web应用程序) 第三篇
接着上节的继续学习,现在要显示所有主题的页面 有了高效的网页创建方法,就能专注于另外两个网页了:显示全部主题的网页以及显示特定主题中条目的网页.所有主题页面显示用户创建的所有主题,它是第一个需要使用数 ...