ASP.NET MVC 音乐商店 - 8. 使用 Ajax 更新的购物车
在这个项目中,我们将允许用户在没有注册登录的情况下将专辑加入购物车,但是,在完成结账的时候必须完成注册工作。购物和结账将会被分离到两个控制器中:一个ShoppingCart 控制器,允许匿名用户使用购物车,另一个Checkout 控制器处理结账。我们先从购物车的控制器开始,然后在下一部分来处理结帐。
加入购物车,订单和订单明细的模型类
在购物车和结账的处理中将会使用到一些新的类,在Models 文件夹上右键,然后使用下面的代码增加一个新的类Cart.
using System.ComponentModel.DataAnnotations;
namespace MvcMusicStore.Models
{
public class Cart
{
[Key]
public int RecordId { get; set; }
public string CartId { get; set; }
public int AlbumId { get; set; }
public int Count { get; set; }
public System.DateTime DateCreated { get; set; }
public virtual Album Album { get; set; }
}
}
这个类非常类似我们前面使用的类,除了RecordId 属性上的[Key] 标注之外。我们的购物车拥有一个字符串类型的名为CartId 的标识,用来允许匿名用户使用购物车,但是,CartId 并不是表的主键,表的主键是整数类型的名为RecordId的字段,根据约定,EF CodeFirst 将会认为表的主键名为CartId 或者Id,不过,如果需要的话,我们可以很容易地通过标注或者代码来重写这个规则。这里例子演示了在使用EF CodeFirst 的时候。当我们的表不是约定的样子时,我们也不必被约定所局限。
下一步,使用下面的代码增加订单Order 类。
using System.Collections.Generic;
namespace MvcMusicStore.Models
{
public partial class Order
{
public int OrderId { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public decimal Total { get; set; }
public System.DateTime OrderDate { get; set; }
public List<OrderDetail> OrderDetails { get; set; }
}
}
这个类跟踪订单的汇总和发货信息,它的结构也不复杂,订单依赖我们这里还没有定义的一个类,通过OrderDetails 属性来表示订单的明细。我们来定义一下这个OrderDetail 类。
namespace MvcMusicStore.Models
{
public class OrderDetail
{
public int OrderDetailId { get; set; }
public int OrderId { get; set; }
public int AlbumId { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public virtual Album Album { get; set; }
public virtual Order Order { get; set; }
}
}
把我们的MusicStoreEntities 更新一下,以便包含我们新定义的模型类,包括艺术家Artist,更新之后的MusicStoreEntities 如下所示。
using System.Data.Entity;
namespace MvcMusicStore.Models
{
public class MusicStoreEntities : DbContext
{
public DbSet<Album> Albums { get; set; }
public DbSet<Genre> Genres { get; set; }
public DbSet<Artist> Artists { get; set; }
public DbSet<Cart> Carts { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
}
}
管理购物车业务逻辑
下一步,我们在Models 文件夹中创建ShoppingCart 类,ShoppingCart 模型类处理 Cart 表的数据访问,另外,它还需要处理在购物车中增加或者删除项目的业务逻辑。
因为我们并不希望用户必须登录系统才可以使用购物车,对于没有登录的用户,我们需要为他们创建一个临时的唯一标识,这里使用GUID,或者被称为全局唯一标识符,对于已经登录的用户,我们直接使用他们的名称,这个表示我们保存在Session 中。
注意:Session 会话可以很方便地存储用户的信息,在用户离开站点之后,这些信息将会过期,滥用Session 信息会对大型站点产生影响,我们这里使用Session 达到演示目的。
ShoppingCart 类提供了如下的方法:
AddToCart, 将专辑作为参数加入到购物车中,在Cart 表中跟踪每个专辑的数量,在这个方法中,我们将会检查是在表中增加一个新行,还是仅仅在用户已经选择的专辑上增加数量。
RemoveFromCart,通过专辑的标识从用户的购物车中将这个专辑的数量减少1,如果用户仅仅剩下一个,那么就删除这一行。
EmptyCart,删除用户购物车中所有的项目。
GetCartItems,获取购物项目的列表用来显示或者处理。
GetCount,获取用户购物车中专辑的数量
GetTotal,获取购物车中商品的总价
CreateOrder,将购物车转换为结账处理过程中的订单。
GetCart ,这是一个静态方法,用来获取当前用户的购物车对象,它使用GetCartId 方法来读取保存当前Session 中的购物车标识,GetCartId 方法需要HttpContextBase 以便获取当前的Session。
实际的代码如下:
namespace MvcMusicStore.Models
{
public partial class ShoppingCart
{
MusicStoreEntities storeDB = new MusicStoreEntities();
string ShoppingCartId { get; set; }
public const string CartSessionKey = "CartId";
public static ShoppingCart GetCart(HttpContextBase context)
{
var cart = new ShoppingCart();
cart.ShoppingCartId = cart.GetCartId(context);
return cart;
}
&nb
补充:Web开发 , ASP.Net ,