ASP.NET MVC3书店第八节 使用Ajax的购物车(第二部分)(转)

http://blog.sina.com.cn/s/blog_6ad539a90100r8gr.html

8.2 实现购物逻辑

    接下来,我们在Models文件夹中添加一个ShoppingCart(购物车)类。这个ShoppingCart模型处理对于Cart(购物车)数据表的数据访问。另外,还处理将书籍添加到购物车与从购物车中删除书籍的业务逻辑。

    因为我们不想要让用户必须经过注册才能将书籍放入购物车中,所以当用户使用购物车时,我们需要指定给用户一个临时唯一标识(使用一个GUID,或者说全球唯一标识符)。我们使用ASP.NET的Session类来存储这个ID。

    请注意:ASP.NET中的Session是一个专门用来存储用户指定的,当用户离开网站时可以作废的信息的类。但是在大的网站中如果滥用Session 类来存储信息的话可能对性能产生影响。本例中我们为了说明问题而向Session类中存入少量信息,对于性能不会产生太大的影响。

    我们将在ShoppingCart类中添加如下所示的几个方法:

  • AddToCart方法:使用一个Book(书籍)对象作为参数,并将该书籍放入购物车中。因为Carts数据表中记录每本书的数量,所以它包括用户在需要时添加一本书的逻辑,或者在购物车中已放入了该书后仅仅修改书籍数量的逻辑。
  •  RemoveFromCart方法:使用一个书籍的ID号作为参数,在该方法中将该书籍从购物车中删除。如果用户仅仅放入了一本书,则该用户的购物车将被清空。
  • EmptyCart方法:清空用户购物车中所有书籍。
  • GetCartItems方法:为了显示或进行后续处理而从购物车中取出所有书籍信息。
  •  GetCount方法:取得用户放在购物车中的书籍数量。
  • GetTotal方法:计算购物车中所有书籍的总价格。

  • CreateOrder方法:在下订单逻辑中根据购物车中所有书籍信息创建订单。

  • GetCart 方法:一个静态(static)方法,允许控制器获得一个cart(购物车)对象。它调用GetCartId方法来从Session中读取用户的 CartId(购物车号)。GetCartId方法需要使用一个HttpContextBase对象来作为参数,以便从用户Session中读取用户的 CartId。

    完整的ShoppingCart类中的代码如代码清单8-5所示。

    代码清单8-5 完整的ShoppingCart类中的代码

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

 namespace MvcBookStore.Models

{

    public partial class ShoppingCart

    {

        BookStoreEntities storeDB = new BookStoreEntities();

        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;

        }

        //使用帮助器方法来简化购物车的访问

        public static ShoppingCart GetCart(Controller controller)

        {

            return GetCart(controller.HttpContext);

        }

        public void AddToCart(Book book)

        {

            //获取对应的购物车对象的实例与书籍对象的实例

            var cartItem = storeDB.Carts.SingleOrDefault(c => c.CartId ==

               ShoppingCartId && c.BookId == book.Id);

            if (cartItem == null)

            {

                //如果购物车中不存在该书籍则添加该书籍

                cartItem = new Cart

                {

                    BookId = book.Id,

                    CartId = ShoppingCartId,

                    Count = 1,

                    DateCreated = DateTime.Now

                };

                storeDB.Carts.Add(cartItem);

            }

            else

            {

                //如果在购物车中该书籍已存在,则添加一个数量

                cartItem.Count++;

            }

            // 保存改变

            storeDB.SaveChanges();

        }

        public int RemoveFromCart(int id)

        {

            //获取购物车对象实例

            var cartItem = storeDB.Carts.Single(cart => cart.CartId ==

              ShoppingCartId && cart.RecordId == id);

            int itemCount = 0;

            if (cartItem != null)

            {

                if (cartItem.Count > 1)

                {

                    cartItem.Count--;

                    itemCount = cartItem.Count;

                }

                else

                {

                    storeDB.Carts.Remove(cartItem);

                }

                // 保存修改

                storeDB.SaveChanges();

            }

            return itemCount;

        }

        public void EmptyCart()

        {

            var cartItems = storeDB.Carts.Where(cart => cart.CartId ==

              ShoppingCartId);

            foreach (var cartItem in cartItems)

            {

                storeDB.Carts.Remove(cartItem);

            }

            // 保存修改

            storeDB.SaveChanges();

        }

        public List<Cart> GetCartItems()

        {

            return storeDB.Carts.Where(cart => cart.CartId ==

              ShoppingCartId).ToList();

        }

        public int GetCount()

        {

            //获取每本书的数量并相加在一起

            int? count = (from cartItems in storeDB.Carts

                          where cartItems.CartId == ShoppingCartId

                          select (int?)cartItems.Count).Sum();

            // 如果实例为null,则返回0

            return count ?? 0;

        }

        public decimal GetTotal()

        {

            //将书籍数量与单价相乘得到每本书的总价,然后相加得到购物车中的总金额

            decimal? total = (from cartItems in storeDB.Carts

                              where cartItems.CartId == ShoppingCartId

                              select (int?)cartItems.Count *

                                  cartItems.Book.Price).Sum();

            return total ?? decimal.Zero;

        }

        public int CreateOrder(Order order)

        {

            decimal orderTotal = 0;

 

            var cartItems = GetCartItems();

            // 在购物车中进行遍历,将每本书放入订单细节中

            foreach (var item in cartItems)

            {

                var orderDetails = new OrderDetail

                {

                    BookId = item.BookId,

                    OrderId = order.OrderId,

                    UnitPrice = item.Book.Price,

                    Quantity = item.Count

                };

                // 将购物车中每本书的价格加入购物车总金额中

                orderTotal += (item.Count * item.Book.Price);

            }

            //用购物车的总金额来设置订单的Total(总金额)属性值

            order.Total = orderTotal;

 

            // 保存订单

            storeDB.SaveChanges();

            // 清空购物车

            EmptyCart();

            // OrderId属性值作为订单编号来返回

            return order.OrderId;

        }

        //使用HttpContextBase类来允许用户使用cookies.

        public string GetCartId(HttpContextBase context)

        {

            if (context.Session[CartSessionKey] == null)

            {

                if (!string.IsNullOrWhiteSpace(context.User.Identity.Name))

                {

                    context.Session[CartSessionKey] =

                       context.User.Identity.Name;

                }

                else

                {

                    //使用System.Guid class创建一个随机GUID

                    Guid tempCartId = Guid.NewGuid();

                    //tempCartId作为一个cookie来发送回客户端

                    context.Session[CartSessionKey] = tempCartId.ToString();

                }

            }

            return context.Session[CartSessionKey].ToString();

        }

        //当用户登陆之后,使用他们的用户名来修改购物车的CartId

        public void MigrateCart(string userName)

        {

            var shoppingCart = storeDB.Carts.Where(c => c.CartId ==

              ShoppingCartId);

            foreach (Cart item in shoppingCart)

            {

                item.CartId = userName;

            }

            storeDB.SaveChanges();

        }

    }

}

8.3 视图模型

    我们的购物车控制器需要将一些复合信息传入视图中,这时视图并不能完全与单个模型对象相匹配。我们不想修改我们的模型来与视图相匹配,因为模型类应该是用 来映射数据库的,而不是用来代表用户界面的。一种解决方法是使用ViewBag类来将信息传入视图,就像我们在前面的编辑模板中使用下拉框时所作的处理那 样,但是如果通过ViewBag来传递大量信息的话,会不利于信息的管理。

    另一种方式是使用视图模型方式。使用这种方式时,我们可以创建强类型的类,这些类是专门为了我们特定的视图而经过优化处理的。它为我们视图提供具有动态值 或动态内容的属性。我们的控制器类可以将这些为了视图而进行优化的类传入视图模板中。这种做法是安全的,编译时检查的,并且在视图模板中具有智能代码输入 功能的。

    我们为购物逻辑添加两个视图模型:ShoppingCartViewModel视图模型将处理用户的购物车中的信息,ShoppingCartRemoveViewModel视图模型将用来在用户从购物车中删除书籍的时候显示确认信息。

    在解决方案资源管理器的工程根文件夹下创建一个新的ViewModels文件夹,如图8-1所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第二部分)

8-1在根文件夹下创建一个新的ViewModels文件夹

    创建完毕后解决方案资源管理器如图8-2所示。

ASP.NET <wbr>MVC3书店--第八节 <wbr>使用Ajax的购物车(第二部分)

图8-2 ViewModels文件夹创建完毕后的解决方案资源管理器

    接下来,在ViewModels文件夹中添加ShoppingCartViewModel类。该类具有两个属性:一个购物车中书籍列表,一个decimal类型的属性来存储购物车中书籍的总金额。代码入下所示。

using System.Collections.Generic;

using MvcBookStore.Models;

 

namespace MvcBookStore.ViewModels

{

    public class ShoppingCartViewModel

    {

        public List<Cart> CartItems { get; set; }

        public decimal CartTotal { get; set; }

    }

}

    接下来,在ViewModels文件夹中追加ShoppingCartRemoveViewModel类,代码如下所示。

namespace MvcBookStore.ViewModels

{

    public class ShoppingCartRemoveViewModel

    {

        public string Message { get; set; }

        public decimal CartTotal { get; set; }

        public int CartCount { get; set; }

        public int ItemCount { get; set; }

        public int DeleteId { get; set; }

    }

}

原文地址:https://www.cnblogs.com/quietwalk/p/2098172.html