How can I keep track of a shopping cart across multiple projects?
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 mac开发者_开发问答hines 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?
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.
精彩评论