1

I know there are a million questions out there on how to implement a shopping cart in your site. However, I think my problem may be somewhat different. I currently have a working shopping cart that I wrote back in the 1.1 days that uses ASP.NET session variables to keep track of everything. This has been in place for about 6 years and has served its purpose well. However, it has come time to upgrade the site and part of what I have been tasked with is creating a more, erm, user-friendly site. Part of this is removing updatepanels and implementing real AJAX solutions.

My problem comes in where I need to persist this shopping cart over several pages. Sure I could use cookies, but I would like to keep track of carts for statistical purposes (abandonment stats, items added but not bought, those kinds of stats) as well as user-friendliness, like persisting their cart so that if they come back it is remembered. This is easy enough if a user is logged in, but I don't want to force a user to create an account if they don't want.

Additionally, the way we were processing orders was a bit, ehh, slapped-together. All of the details (color selected, type selected, etc) are passed to paypal via their description string which for the most part is ok, but if a product has selections that are too long for the string (255 chars i believe), they are cut off and we have to call the customer to confirm what they bought. If I were to implement a more "solid" shopping cart, we wouldn't have to do that because all the customer's choices would be stored, in addition to the order automatically being entered into the order processing system (they're manually entered into an excel spreadsheet. i know, right).

I want to do this the right way, but I don't want to use any sort of overblown software that won't really work with our current business model. Do I use a cookie to "label" each visitor to match them with their cart (give them a cookie with a GUID) across pages, keep their whole cart client side, keep the cart server side and just pull it from the db on each page refresh? Any help would be greatly appreciated.

Thanks!

Jason
  • 51,583
  • 38
  • 133
  • 185

2 Answers2

3

So this isn't really the answer to your question, but it is part of the answer. I'm trying to find the duplicate that this is of (it may not be) but you can keep a lot of the same code if you'll use IRequiresSessionState. I didn't find any exact duplicates, but I recognized the subject matter.

Handler with IRequiresSessionState does not extend session timeout

other answers:

ASP.NET: How to access Session from handler?

Authentication in ASP.NET HttpHandler

So what you want to really do is just look to implement PageMethods in your pages, and then you can reduce a LOT of the overhead of communicating with the pages. But if you want to migrate away from what you're doing now you want to start implementing handlers (and configure them to use JSON - there's a decorator for that) and you can use that with the likes of jQuery.ajax() as a direct URL and keep it within the same scope of your project. Note that it will by default send the cookies for you, so that's no big deal. The reason why I say that is that the cookie has the identifier from Forms to let the session be identified.

So if you're using the IRequireSessionState then you can still use all the session state information that you're used to using. There's nothing wrong with using Session in combination with AJAX. The two really don't have a lot to do with each other. One is used for server storage, the other is used for server communication.

Now, if you're trying for a completely clientside app and a RESTful server solution, then you're going to need to start passing complex JSON structures back and forth (not a big deal, just a matter of making sure you define your datatypes for yourself pretty well in your own documentation) and you can keep everything restricted to only what's passed.

I actually use all three types of these methods in my applications on the same server, depending on what I'm trying to do with each of my apps. I have found that each has their own strength and weakness. (Ok, I don't use the session part, because I handle my state in other ways, but I could use session state)

What could I clarify with here?

Community
  • 1
  • 1
jcolebrand
  • 15,889
  • 12
  • 75
  • 121
  • interesting. so in theory i could build the cart on the back end and just populate the cart each time because it's held in sessionstate? kind of like a static variable? – Jason Feb 05 '11 at 01:10
  • @Jason Yep. That's the idea. So you could reuse most of the logic you already have. I'm all about not totally destroying the original if you don't have to, and supporting six years of existence is important. This at least also allows you to start developing handlers and getting more and more handler/javascript dependent without giving up what you already have. – jcolebrand Feb 05 '11 at 01:13
  • yeah that's the idea... eventually i'm going to convert to mvc, but until then i'm trying to convert everything into handlers. when i get to a point where i can test my implementation, i will post w/my results – Jason Feb 05 '11 at 01:17
  • @Jason ~ Cool. I know it'll go well. Best of luck and hopefully it goes smoother than you expect, and faster at that. Also keep in mind using PageMethods as a way to start playing with AJAX webmethods (but turn to jQuery.ajax() before too long of course) – jcolebrand Feb 05 '11 at 01:18
  • thank you so much for the effort put in to this answer. i will definitely keep both of you apprised of my progress via this question. – Jason Feb 05 '11 at 02:00
2

There are a few ways you can handle this. The main question is how long do you need to persist their shopping cart information (30minutes, 1 hour, 1 day, 1 week, ...etc.).

Short Storage Requirements Easiest Implementation (30min - 1hr)

You can use session with Page Methods by using HttpContext.Current.Session["key"] so you can keep your session storage the same as it currently works for you. You can call these Page Methods using jquery ajax pretty easily and would eliminate the need for update panels, a script manage, etc. So it gets you halfway there in my opinion. Your pages will load faster and be more responsive and you don't have to throw away any of the code involved with caching stuff in session. Main downside to this is that you are still using session so you really don't want to persist sessions for too long as that will bog down the server hosting a site if it is fairly active.

Long Storage Requirements Server Side implementation

Same stuff above applies except you are not using session and you can use stateless web services if you like. You would generate a GUID for each visitor and storing that GUID in a cookie. On each ajax call you would send this GUID along with the data to persist. This info would get stored in a database identified by the GUID. If the customer completes their order then the information can be moved from the cache database to the completed orders database. In this implementation you would want to write some service or scheduled job that would delete cached orders (not completed) after a certain amount of time to keep the cache database lean.

Nice thing about this solution is you can have a pretty long lived cache, write some reports that key off this cached data, and the load on your web server will be reduced. Additionally if your site becomes more popular it is easy to scale out because you don't have to worry about keeping sessions in sync across multiple web servers.

Long Storage Requirements Client Side Implementation

This approach still uses web services or page methods but there is no caching database involved. Essentially you jam all your information into a cookie or set of cookies and key off that. You might still be able to get some information if you read out the contents of the cookie(s) on each POST and store that somewhere to report off of.

If you don't need to track what customers added things but didn't order then the major benefit of this solution is that you can cut the amount of POST's you have to do down by a lot. You can write to the cookie(s) in javascript and just POST everything when they are completing their order. Just be careful not to put any sensitive information in the cookies unencrypted (contact info, billing info, ..etc.) as there are ways to mine data in cookies from other domains in some less secure browsers. For the sensitive stuff you would POST it to the server and have it returned the encrypted information for storage in the cookie(s).

Downside to this solution is that if the information you need to store is large you could run up against the max cookie size and/or max number of cookies per domain limitation. With a good strategy (ie. storing product id's not product description) you will probably be ok.

Let me know if any of the above is unclear or if you have additional questions.

EDIT: Didn't see the answer above that essentially lays out the Short Storage Requirements one I have. If that is the accepted solution give him the check mark (he beat me to it (= ). Leaving my answer as it lays out some additional options.

Adrian
  • 2,911
  • 1
  • 17
  • 24
  • For the record, you don't need to put that sort of footer ;) but you're right, you do explore a lot more options. I just wanted to take the option of letting him use his existing code. But I would personally back mine to a database and go off a key value. ;) – jcolebrand Feb 05 '11 at 01:55
  • thank you for this answer as well. i had kind of assumed i was going to have to do something like this, but your answer lays it out nicely for me. – Jason Feb 05 '11 at 01:59
  • 1
    @drachenstern Wanted to put in that footer because my first option is essentially your post reworded. Even though I didn't use your post as a basis for mine you were first so if that is the route the poster is going to go you should get the credit (= – Adrian Feb 05 '11 at 02:06