购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)–后端

购物车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) > 0;
    }
    
    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) > 0;
    }
}

 

再细节。

 

//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) > 0;
    }
}

 

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);
}

 

待续~~

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109250.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 微信小程序列表页面_微信发现没有小程序

    微信小程序列表页面_微信发现没有小程序尽量不要用缓存去写效果展示:点击编辑,进入编辑页第一页编辑按钮:<viewclass=”bj-btn”bindtap=”redactGroup”data-id=”{{传递的id}}”>编辑</view>redactGroup方法:options.currentTarget.dataset.前面自定义的名字redactGroup(options){letid=options.currentTarget.dataset.id;…

    2022年8月18日
    12
  • Java开发不得不会!郑州java外包公司有哪些

    Java开发不得不会!郑州java外包公司有哪些拼多多三面惨败,java中间件、数据库与spring框架,答不上…面试开火箭,工作拧螺丝…月初有个朋友面试拼多多,一面自信满满过了,结果三面却惨败…昨天朋友约我出来讨论问题在哪里,三面就答不上了(卡壳很严重呐)。听完整个面试经历之后,我总结了一下,这次拼多多一二三面其实综合总结起来就问了五个方面的东西,分别是自我介绍+项目、java基础、中间件、数据库和spring框架,另外还问了道算法题。接下来就跟大家一起来看看拼多多的面经,看看你是否能轻松应对面试官的炮轰?技术焦虑现在的技术圈子很火热,任何技术

    2022年5月11日
    64
  • EL表达式

    EL表达式EL表达式

    2022年4月25日
    52
  • gcc基本命令_cmake 命令

    gcc基本命令_cmake 命令介绍GCC(英文全拼:GNUCompilerCollection)是GNU工具链的主要组成部分,是一套以GPL和LGPL许可证发布的程序语言编译器自由软件,由RichardStallman于1985年开始开发。GCC原名为GNUC语言编译器,因为它原本只能处理C语言,但如今的GCC不仅可以编译C、C++和Objective-C,还可以通过不同的前端模块支持各种语言,包括Java、Fortran、Ada、Pascal、Go和D语言等等。编译过程GC

    2022年10月13日
    3
  • JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙!

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 作者:fredal https://fredal.xin/java-error-check CPU 磁盘 内存 GC…

    2021年6月24日
    92
  • python删除文件指定行

    python删除文件指定行我们现在有五行数据,我们想删除第三行:pig删除文本指定行:删除文本指定行用的是foriini,找到指定行的关键字,将不包括关键字的其他行放在生成器中,将生成器包含的内容重新写入文件。我们这里不用readlines是因为foriinf是使用一行读取一行,不会消耗太多的内存。如果使用readlines就会一次性将所有的内容全部读取出来放在内存当中,会占用较多的内存,且不方便我们对…

    2022年5月30日
    166

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号