购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端
chsakell分享了前端使用AngularJS,后端使用ASP.NET Web API的购物车案例,非常精彩,这里这里记录下对此项目的理解。
文章:
http://chsakell.com/2015/01/31/angularjs-feat-web-api/
http://chsakell.com/2015/03/07/angularjs-feat-web-api-enable-session-state/
源码:
https://github.com/chsakell/webapiangularjssecurity
本系列共三篇,本篇是第一篇。
购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端
购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session
购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证
■ 配置EF
首先搞清模型之间的关系:
- public class Gadget
- {
- public int GadgetID{get;set;}
- ...
- public int CategoryID{get;set;}
- public Category Category{get;set;}
- }
- public class Category
- {
- public int CategoryID{get;set;}
- ...
- public List<Gadget> Gadgets{get;set;}
- }
- public class Order
- {
- public int OrderID{get;set;}
- ...
- public List<Gadget> Gadgets{get;set;}
- }
- public class GadgetOrder
- {
- public int GadgetOrderID{get;set;}
- public int OrderID{get;set;}
- public Order Order{get;set;}
- public int GadgetID{get;set;}
- public Gadget Gadget{get;set;}
- }
以上,Category和Gadget是1对多的关系,GadgetOrder是Order和Gadget的中间表。
接着需要通过EF Fluent API来配置领域,需要实现EntityTypeConfiguration<TModel>这个基类。比如:
- public class OrderConfiguration : EntityTypeConfiguration<Order>
- {
- public OrderConfiguration()
- {
- Ignore(o => o.Gadgets);
- }
- }
然后就配置上下文,继承DbContext这个基类。
- public class StoreContext : DbContext
- {
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- ...
- modelBuilder.Configurations.Add(new OrderConfiguration());
- }
- public DbSet<Order> Orders{get;set;}
- ...
- }
我们还希望在生成数据库的时候生成一些种子数据,需要继承DropCreateDatabaseIfModelChanges<TContext>这个泛型类。
- public class StoreInitializer : DropCreateDatabaseIfModelChanges<StoreContext>
- {
- protected override void Seed(StoreContext context)
- {
- try
- {
- GetCategoreis().ForEach(c => context.Categories.Add(c));
- ...
- }
- catch(Exception ex)
- {
- Debug.WriteLine(ex.Message);
- }
- }
- private static List<Category> GetCategories()
- {
- ...
- }
- }
如何调用数据库种子数据的类StoreInitializer呢?有一种方法使在项目全局文件中配置。(还有一种方法使在DbContext的构造函数中配置,还有一种在数据库迁移文件中配置,etc.)
- void Application_Start(object sender, EventArgs e)
- {
- Database.SetInitializer(new StoreIntializer());
- }
最后,关于EF的配置部分,需要在Web.config中配置,大致如下:
- <connectionStrings>
- <add name="ProductServiceContext" connectionString="Data Source=.;User=someusername;Password=somepassword;Initial Catalog=MyProductService;Integrated Security=True" providerName="System.Data.SqlClient"/>
- </connectionStrings>
■ CategoriesController
先俯瞰。
- public class CategoriesController : ApiController
- {
- private StoreContext db = new SotoreContext();
- ...
- private bool CategoryExists(int id)
- {
- return db.Categories.Count(g => g.CategoryID=id) > ;
- }
- protected override void Dispose(boo disposing)
- {
- if(disposing)
- {
- db.Dispose();
- }
- base.Dispose(disposing);
- }
- }
再细节。
- /GET api/Categories
- public IQueryable<Category> GetCategories()
- {
- return db.Categories;
- }
- //GET api/Categories/5
- [ResponseType(typeof(Category))]
- public async Task<IHttpActionResult> GetCategory(int id)
- {
- Category category = await db.Categories.FindAsync(id);
- if(category == null)
- {
- return NotFound();
- }
- return Ok(category);
- }
- //put api/Categories/5
- [ResponseType(typeof(void))]
- public async Task<IHttpActionResult> PutCategory(int id, Category category)
- {
- if(!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
- if(id != category.CategoryID)
- {
- return BadRequest();
- }
- db.Entry(category).State = EntityState.Modified;
- try
- {
- await db.SavheChangesAsync();
- }
- catch(DbUpdateConcurrencyException)
- {
- if(!CategoryExists(id))
- {
- return NotFound();
- }
- else
- {
- throw;
- }
- }
- return StatusCode(HttpStatusCOde.NoContet);
- }
- //post api/Categories
- [ResponseType(typeof(Category))]
- public async Task<IHttpActionResult> PostCategory(Category category)
- {
- if(!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
- db.Categories.Add(category);
- await db.SaveChangesAsync();
- //返回到指定的路由
- return CreatedAtRoute("DefaultApi", new {id = category.CategoryID}, category);
- }
- //delete api/Categoreis/5
- [ResponseType(typeof(Category))]
- public async Task<IHttpActionResult> DeleteCategory(int id)
- {
- Category category = await db.Categories.FindAsync(id);
- if(category == null)
- {
- return NotFound();
- }
- db.Categories.Remove(category);
- await db.SaveChangesAsync();
- return Ok(category);
- }
■ GadgetsController
先俯瞰。
- public class GadgetsController : ApiController
- {
- private StoreContext db = new StoreContext();
- protected override void Dispose(bool disposing)
- {
- if(disposing)
- {
- db.Dispose();
- }
- base.Dispose(disposing);
- }
- private bool GadgetExists(int id)
- {
- return db.Gadgets.Count(g => g.GadgetID == ID) > ;
- }
- }
再细节。
- //get api/Gadgets
- public IQueryable<Gadget> GetGadgets()
- {
- return db.Gadgets;
- }
- //get api/Gadgets/5
- [ResponseType(typeof(Gadgets))]
- public async Task<IHttpActionResult> GetGadget(int id)
- {
- Gadget gadget = await db.Gadgets.FindAsync(id);
- if(gadget == null)
- {
- return NotFound();
- }
- return Ok(gadget);
- }
- //put api/Gadgets/5
- [ResponseType(typeof(void))]
- public async Task<IHttpActionResult> PutGadget(int id, Gadget gadget)
- {
- if(!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
- if(d != gadget.GadgetID)
- {
- return BadRequest();
- }
- db.Entry(gadget).State = EntityState.Modified;
- try
- {
- await db.SaveChangesAsync();
- }
- catch(DbUpdateConcurrencyException)
- {
- if(!GadgetExists(id))
- {
- return NotFound();
- }
- else
- {
- throw;
- }
- }
- }
- //post api/Gadgets
- [ResposneType(typeof(Gadget))]
- public async Task<IHttpActionResult> PostGadget(Gadget gadget)
- {
- if(!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
- db.Gadgets.Add(gadget);
- await db.SaveChangesAsync();
- return CreatedAtRoute("DefaultApi", new {id=gadget.GadgetID}, gadget)
- }
- //delete api/Gadgets/5
- [ResponseType(typeof(Gadget))]
- public async Task<IHttpActionResult> DeleteGadget(int id)
- {
- Gadget gadget = await db.Gadgets.FindAsync(id);
- if(gadget == null)
- {
- return NotFound();
- }
- db.Gadgets.Remove(gadget);
- await db.SaveChangesAsync();
- return Ok(gadget);
- }
■ OrdersController
firstly overview.
- public class OrdersController : ApiController
- {
- private StoreContext db = new StoreContext();
- protected override void Dispose(bool dispoing)
- {
- if(disposing)
- {
- db.Dispose();
- }
- base.Dispose(disposing);
- }
- private bool OrderExists(int id)
- {
- return db.Orders.Count(g => g.OrderID == id) > ;
- }
- }
then details.
- // get api/Orders
- public IQueryable<Order> GetOrders()
- {
- return db.Orders;
- }
- //get api/Orders/5
- [ResponseType(typeof(Order))]
- public async Task<IHttpActionResult> GetOrder(int id)
- {
- Order order = await db.Orders.FindAsync(id);
- if(order == null)
- {
- return NotFound();
- }
- return Ok(order);
- }
- //put api/Orders/5
- [ResponseType(typeof(void))]
- public async Task<IHttpActionResult> PutOrder(int id, Order order)
- {
- if(!ModelState.IsValid)
- {
- return BadRequest(ModelState);
- }
- if(id != order.OrderID)
- {
- return BadRequest();
- }
- db.Entry(order).State = EntityState.Modified;
- try
- {
- await db.SaveChangesAsync();
- }
- catch(DbUpdateConcurrecyException)
- {
- if(!OrderExists(id))
- {
- return NotFound();
- }
- else
- {
- throw;
- }
- }
- return StatusCode(HttpStatusCOde.NoContet);
- }
- //post api/Orders
- [RequestType(typeof(Order))]
- public async Task<IHttpActionResult> PostOrder(Order order)
- {
- if(!ModelState.IsValid)
- {
- reuturn BadRequest(ModelState);
- }
- try
- {
- db.Orders.Add(order);
- foreach(Gadget gadget in order.Gadgets)
- {
- db.GadgetOrders.Add(new GadgetOrder{
- OrderID = order.OrderID,
- GadgetID = gadget.GadgetID
- })
- }
- await db.SaveChangesAsync();
- }
- catch(Exception ex)
- {
- return BadRequest(ex.Message);
- }
- return CreatedAtRoutne("Default", new {controller = "Home", action="viewOrder", id = order.orderID}, order);
- }
- //delete api/Orders/5
- [ResponseType(typeof(Order))]
- public async Task<IHttpActionResult> DeleteOrder(int id)
- {
- Order order = await db.Orders.FindAsync(id);
- if(order == null)
- {
- return NotFound();
- }
- db.Orders.Remoe(order);
- await db.SaveChangesAsync();
- return Ok(order);
- }
待续~~
购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端的更多相关文章
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证 chsakell分享了前端使用AngularJS,后端使用ASP. ...
- 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session
原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session chsakell分享了前端使用AngularJS,后端使用ASP.NE ...
- 对一个前端AngularJS,后端OData,ASP.NET Web API案例的理解
依然chsakell,他写了一篇前端AngularJS,后端OData,ASP.NET Web API的Demo,关于OData在ASP.NET Web API中的正删改查没有什么特别之处,但在前端调 ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(4)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(3)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(2)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(1)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- 前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查
AngularJS中的$resource服务相比$http服务更适合与RESTful服务进行交互.本篇后端使用ASP.NET Web API, 前端使用$resource,实现增删改查. 本系列包括: ...
- ASP.NET Web API 2 external logins with Facebook and Google in AngularJS app
转载:http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-a ...
随机推荐
- 小qyvlik 先看两个视频,和 QtQuick UI 问答
http://edu.csdn.net/course/detail/1042 http://edu.csdn.net/course/detail/335 http://blog.csdn.net/qy ...
- 哪些产品不用开发原生APP,微信公众号就够了?
最近一阶段H5技术被推到高峰,很多人认为借助H5就能利用微信公众号取代APP原生应用了,而事实是怎么样的?这里我从产品层做一个客观分析. 一,原生APP总体趋势 要谈APP是否会被微信取代,那么必须回 ...
- 【转】Android API 中文(14) —— ViewStub
用一个XML源填充view.inflate(上下文对象,资源文件Id,父窗口组一般为null): 原文网址:http://www.cnblogs.com/over140/archive/2010/10 ...
- ZOJ3765---Lights (Splay伸展树)
Lights Time Limit: 8 Seconds Memory Limit: 131072 KB Now you have N lights in a line. Don't wor ...
- 【译】Javascript中的数据类型
这篇文章通过四种方式获取Javascript中的数据类型:通过隐藏的内置[[Class]]属性:通过typeof运算符:通过instanceof运算符:通过函数Array.isArray().我们也会 ...
- POJ 3378
题目链接 查找长度为5的上升序列总数 用的树状数组+高精度 用树状数组求在i前面比i小的数有几个 用的4个树状数组,A[i][j]表示长度为i的以j为结尾的个数,A[i][j]=A[i-1][1... ...
- python批量下载
# -*- coding: utf-8 -*-__author__ = 'Administrator'from PyQt4.Qt import *from PyQt4.QtCore import *f ...
- 一个js编写全选、弹出对话框、ajax-json的案例
js功能有:全选.弹出对话框.使用json传输ajax数据:不想在写多余的文字了,直接上代码: <%@ page language="java" contentType=&q ...
- Timus 1796. Amusement Park 聪明题
On a sunny Sunday, a group of children headed by their teacher came to an amusement park. Aunt Frosy ...
- JMeter分布式性能测试
利用JMeter进行负载测试的时候,使用单台机器模拟测试超过1000个行程的并发就有些力不从心,在执行的过程中,JMeter自身会自动关闭,要解决这个问题,可以使用分布式测试,运行多台机器运行所谓的 ...