Asp .net WebApi 实践系列(一)webapi服务端+bootstrap+jq响应式异步请求Demo
这一系列文章,是我在大牛的博客里学到的,代码和那位大牛的几乎相似,跟随大牛的脚步,持续学习中。
这个webapi简单Demo的步骤有一下几步:
1.建立一个webapi项目
2.新建Book类
3.IBookRepository和BookRepository类
4.添加BooksController
5.修改Index.cshtml前端文件
简单WEBAPI项目
Book类
public class Book { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } }
IBookRepository类
public interface IBookRepository { IEnumerable<Book> GetAll(); Book Get(int id); Book Add(Book book); void Remove(int id); bool Update(Book book); }
BookRepository类
public class BookRepository:IBookRepository { private MvcAndApiContext db = new MvcAndApiContext(); 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); } }
还有CodeFirst那一套
public class MvcAndApiContext : DbContext { // You can add custom code to this file. Changes will not be overwritten. // // If you want Entity Framework to drop and regenerate your database // automatically whenever you change your model schema, please use data migrations. // For more information refer to the documentation: // http://msdn.microsoft.com/en-us/data/jj591621.aspx public MvcAndApiContext() : base("name=MvcAndApiContext") { } public System.Data.Entity.DbSet<MvcAndApi.Models.Book> Books { get; set; } }
public class BookInitializer:DropCreateDatabaseIfModelChanges<MvcAndApiContext> { protected override void Seed(MvcAndApiContext 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 }); } }
<add name="MvcAndApiContext" connectionString="Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=MvcAndApiContext-20170412085607; Integrated Security=True; MultipleActiveResultSets=True; AttachDbFilename=|DataDirectory|MvcAndApiContext-20170412085607.mdf" providerName="System.Data.SqlClient" />
关键是BooksController的代码和我们之前的MVC几乎一样就是继承的基类不同(响应管道不同,这里我只知道皮毛,后续会详细研究)
using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using System.Web.Http.Description; using MvcAndApi.Models; namespace MvcAndApi.Controllers { public class BooksController : ApiController { //_repository运行时变量,在首次引用IBookRepository方法时动态分配内存 public IBookRepository _repository = new BookRepository(); //根据惯例,如果action名称以Get开头,那就接收Get请求 public IEnumerable<Book> GetAllBooks() { return _repository.GetAll(); } //ASP.NET Web API会自动帮我们把URL中的字符串id转换成参数类型int public 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); //返回新创建资源的url string 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); } } }
然后就是前台代码(运动jq的ui和tmpl)
@section scripts { <script src="@Url.Content("~/Scripts/jquery-1.10.2.js")" type="text/javascript"> </script> <script src="@Url.Content("~/Scripts/jquery-ui-1.12.1.min.js")" type="text/javascript"> </script> <script src="@Url.Content("~/Scripts/jquery.loadTemplate-1.4.4.min.js")"></script> <link href="~/Content/bootstrap.min.css" rel="stylesheet" /> <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="images/ajax-loader.gif" /> <ul id="books" class="books"></ul> </div> </div> </div> <br class="clear" /> <div class="footer clearfix"> </div> </form> </body>
结果显示
后续继续学习webapi