问题
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