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

简介: 原文:购物车Demo,前端使用AngularJS,后端使用ASP.NET Web API(1)--后端  chsakell分享了前端使用AngularJS,后端使用ASP.NET Web API的购物车案例,非常精彩,这里这里记录下对此项目的理解。
原文: 购物车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);
}

 

待续~~

 

目录
相关文章
|
4月前
|
开发框架 缓存 .NET
并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流
并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流
215 0
|
3月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
3月前
|
开发框架 .NET 中间件
ASP.NET Core Web 开发浅谈
本文介绍ASP.NET Core,一个轻量级、开源的跨平台框架,专为构建高性能Web应用设计。通过简单步骤,你将学会创建首个Web应用。文章还深入探讨了路由配置、依赖注入及安全性配置等常见问题,并提供了实用示例代码以助于理解与避免错误,帮助开发者更好地掌握ASP.NET Core的核心概念。
101 3
|
3月前
|
开发框架 前端开发 .NET
VB.NET中如何利用ASP.NET进行Web开发
在VB.NET中利用ASP.NET进行Web开发是一个常见的做法,特别是在需要构建动态、交互式Web应用程序时。ASP.NET是一个由微软开发的开源Web应用程序框架,它允许开发者使用多种编程语言(包括VB.NET)来创建Web应用程序。
61 5
|
4月前
|
XML 开发框架 .NET
ASP.NET Web Api 如何使用 Swagger 管理 API
ASP.NET Web Api 如何使用 Swagger 管理 API
110 1
|
4月前
|
开发框架 JSON .NET
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
ASP.NET Core 标识(Identity)框架系列(三):在 ASP.NET Core Web API 项目中使用标识(Identity)框架进行身份验证
|
4月前
|
开发框架 .NET API
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
195 3
|
4月前
|
开发框架 监控 .NET
开发者的革新利器:ASP.NET Core实战指南,构建未来Web应用的高效之道
【8月更文挑战第28天】本文探讨了如何利用ASP.NET Core构建高效、可扩展的Web应用。ASP.NET Core是一个开源、跨平台的框架,具有依赖注入、配置管理等特性。文章详细介绍了项目结构规划、依赖注入配置、中间件使用及性能优化方法,并讨论了安全性、可扩展性以及容器化的重要性。通过这些技术要点,开发者能够快速构建出符合现代Web应用需求的应用程序。
60 0
|
4月前
|
存储 开发框架 .NET
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
|
4月前
|
开发框架 .NET API
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
195 0