How can I keep track of a shopping cart across multiple projects?

自作多情 提交于 2019-12-24 06:07:29

问题


First some background, we are creating a new "eGov" application. Eventually, a citizen can request permits and pay for licenses along with pay their utility bills and parking tickets online. Our vision has a shopping cart so a person can pay for multiple items in one transaction. To keep things organized better, we are going to break each section into a different project. This also allows me to work on one project while the other developer works another. The person making a payment could be a registered user or could remain unregistered. We feel a person from out of our jurisdiction probably doesn't want to register just to pay their parking ticket or pay for a one-time business license.

This project will be on Windows Server 2008 and IIS7 and using ASP.NET MVC 3. We will probably use a single domain (maybe egov.domain.gov) and in multiple sub directories (/cart, /permit, /billing, etc) though that is not 100% decided yet.

Now the problem. How do we track a shopping cart across multiple projects? There was talk of using a cookie that expires at a certain point or using a state machine. We are uncertain if using a session id would work. If we use a state machine, I have never used that and only understand it in concept (it works across multiple machines and SO uses it).

One other note, we are going to be building this on a VMWare server, so the possibility of having this run across multiple servers is a possibility in the future.

What would you use and why?

Update: It appears like many seem to recommend storing the cart in HttpContext. Is this the same across multiple applications?


回答1:


First you need to setup your SQL Server to accept session state connections.

  • Article 1
  • Article 2

Then add the following to your Web.config file:

<sessionState mode="SQLServer" sqlConnectionString="Server=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=ASPState;Application Name=name" timeout="20" allowCustomSqlDatabase="true" />` within `<system.web>

I then created a class library that has two classes: Cart and CartItem.

CartItem defined to hold each individual shopping cart item

[Serializable]
public class CartItem
{
    [Key]
    public int RecordId { set; get; }
    public string ItemNumber { set; get; }
    public string Description { set; get; }
    public DateTime DateTimeCreated { set; get; }
    public decimal Cost { get; set; }
}

Cart works with your shopping cart

public class Cart
{
    HttpContextBase httpContextBase = null;
    public const string CartSessionKey = "shoppingCart";

    /// <summary>
    /// Initializes a new instance of the <see cref="ShoppingCart"/> class.
    /// </summary>
    /// <param name="context">The context.</param>
    public Cart(HttpContextBase context)
    {
        httpContextBase = context;
    }

    /// <summary>
    /// Gets the cart items.
    /// </summary>
    /// <returns></returns>
    public List<CartItem> GetCartItems()
    {
        return (List<CartItem>)httpContextBase.Session[CartSessionKey];
    }

    /// <summary>
    /// Adds to cart.
    /// </summary>
    /// <param name="cartItem">The cart item.</param>
    public void AddToCart(CartItem cartItem)
    {
        var shoppingCart = GetCartItems();

        if (shoppingCart == null)
        {
            shoppingCart = new List<CartItem>();
        }

        cartItem.RecordId = shoppingCart.Count + 1;
        cartItem.DateTimeCreated = DateTime.Now;
        shoppingCart.Add(cartItem);

        httpContextBase.Session[CartSessionKey] = shoppingCart;
    }

    /// <summary>
    /// Removes from cart.
    /// </summary>
    /// <param name="id">The id.</param>
    public void RemoveFromCart(int id)
    {
        var shoppingCart = GetCartItems();
        var cartItem = shoppingCart.Single(cart => cart.RecordId == id);
        shoppingCart.Remove(cartItem);
        httpContextBase.Session[CartSessionKey] = shoppingCart;
    }

    /// <summary>
    /// Empties the cart.
    /// </summary>
    public void EmptyCart()
    {
        httpContextBase.Session[CartSessionKey] = null;
    }

    /// <summary>
    /// Gets the count.
    /// </summary>
    /// <returns></returns>
    public int GetCount()
    {
        return GetCartItems().Count;
    }

    /// <summary>
    /// Gets the total.
    /// </summary>
    /// <returns></returns>
    public decimal GetTotal()
    {
        return GetCartItems().Sum(items => items.Cost);
    }
}

To test this, first in my shopping cart project in my home controller I did the following:

    public ActionResult Index()
    {
        var shoppingCart = new Cart(this.HttpContext);
        var cartItem = new CartItem
        {
            Description = "Item 1",
            ItemNumber = "123"
            Cost = 20,
            DateTimeCreated = DateTime.Now
        };

        shoppingCart.AddToCart(cartItem);

        cartItem = new CartItem
        {
            Description = "Item 2",
            ItemNumber = "234"
            Cost = 15,
            DateTimeCreated = DateTime.Now
        };

        shoppingCart.AddToCart(cartItem);

        var viewModel = new ShoppingCartViewModel
        {
            CartItems = shoppingCart.GetCartItems(),
            CartTotal = shoppingCart.GetTotal()
        };

        return View(viewModel);
    }

In my second project's home controller, I added the following:

    public ActionResult Index()
    {
        var shoppingCart = new Cart(this.HttpContext);
        var cartItem = new CartItem
        {
            Description = "Item 3",
            ItemNumber = "345"
            Cost = 55,
            DateTimeCreated = DateTime.Now
        };

        shoppingCart.AddToCart(cartItem);

        return View();
    }

This seemed to work for me great.



来源:https://stackoverflow.com/questions/7389492/how-can-i-keep-track-of-a-shopping-cart-across-multiple-projects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!