原文:购物车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)--后端的更多相关文章

  1. 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证

    原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(3)--Idetity,OWIN前后端验证 chsakell分享了前端使用AngularJS,后端使用ASP. ...

  2. 购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session

    原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(2)--前端,以及前后端Session chsakell分享了前端使用AngularJS,后端使用ASP.NE ...

  3. 对一个前端AngularJS,后端OData,ASP.NET Web API案例的理解

    依然chsakell,他写了一篇前端AngularJS,后端OData,ASP.NET Web API的Demo,关于OData在ASP.NET Web API中的正删改查没有什么特别之处,但在前端调 ...

  4. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(4)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  5. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(3)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  6. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(2)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  7. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(1)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

  8. 前端使用AngularJS的$resource,后端ASP.NET Web API,实现增删改查

    AngularJS中的$resource服务相比$http服务更适合与RESTful服务进行交互.本篇后端使用ASP.NET Web API, 前端使用$resource,实现增删改查. 本系列包括: ...

  9. 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 ...

随机推荐

  1. 用keil直接生成BIN文件

    1.下载hex2bin到keil的任意目录,下载地址:http://www.keil.com/download/docs/7.asp 或者 http://www.hex2bin.com/files/h ...

  2. Android Animations简介

    一 .Animations简介 Animations提供了一系列的动画效果,这些效果可以应用于绝大多数的控件: 二.Animations的分类 第一类:TweenedAnimations,该类Anim ...

  3. [每日一题] 11gOCP 1z0-052 :2013-09-27 bitmap index.................................................C37

    转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/12106027 正确答案C 这道题目是需要我们掌握位图索引知识点. 一.首先我们来看位图索引 ...

  4. html p标签换行问题

    /*p标签自动换行*/ p{ word-wrap:break-word; word-break:normal; } /*p强制不换行*/ p{ white-space:nowrap; } /*块级元素 ...

  5. java_IO流小结

    字符流和字节流的主要区别: 1.字节流读取的时候,读到一个字节就返回一个字节:  字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时.先去查指定的编码表,将 ...

  6. MVC 区域模块

    mvc4.0新增的area区域机制,可以协助你在架构较为大型的项目,让独立性较高的部分功能独立成一个MVC子网站,以降低网站与网站之间的耦合性,也可以通过area的切割,让多人同时开发同一个项目时候, ...

  7. 为人们服务的asp.net 验证控件

    ASP.NET是微软推出的WEB开发工具,他有很强大的功能,今天看视频讲到验证控件这一部分,真的感受到了微软全心全意为人民服务了.越来越佩服微软了,人家都设计出来了,咱们一定要会用才可以啊,不然太…. ...

  8. hadoop集群监控工具ambari安装

    Apache Ambari是对Hadoop进行监控.管理和生命周期管理的基于网页的开源项目.它也是一个为Hortonworks数据平台选择管理组建的项目.Ambari支持管理的服务有: Apache ...

  9. Java MongoDB 资料集合

    一.Mongodb介绍及对比 1.NoSQL介绍及MongoDB入门 http://renial.iteye.com/blog/684829 2.mongoDB 介绍(特点.优点.原理) http:/ ...

  10. QiniuUpload- 一个方便用七牛做图床然后插入markdown的小工具

    最近一段时间有用markdown做笔记,其他都好,但是markdown插入图片挺麻烦的,特别是想截图之后直接插入的时候.需要首先把图片保存了,然后还要上传到一个地方生成链接才能插入.如果有个工具可以直 ...