Syllabus Schedule Project Labs Canvas Server Access CSS Tutorial Assignment 1 Assignment 2 Assignment 3 Assignment 4 Assignment 5 Assignment 6 Assignment 7 Assignment 8 Assignment 9

Assignment 8 - Shopping Cart & Customer Info

This week you will create a shopping cart and write customer information to the database.

Shopping cart data can be stored using cookies, a database, or session. The database approach is the most robust approach and is used by Amazon and other large e-commerce sites. Advantages of this approach are that the data persists indefinitely and the user can retrieve their cart items from different devices (with a login). Storing shopping cart data in a database also allows user behavior to be analyzed (data mining) for insights on how to improve the site and its features.

Users typically are not required to sign-in to use a shopping cart since this could deter people from putting items in their cart. This creates a challenge since the web site needs a method for tracking the state of individual users. Fortunately ASP.NET (and most server-side programming frameworks) automatically creates a unique identifier for each user, the SessionID. It is a string of 24 random letters and numbers that is stored in a cookie on the user's computer and is included with each request. The session ID may be retrieved with "Session.SessionID". When using a database shopping cart this ID is written to the database along with the cart data.

  1. tblCart music/detail - Currently the music store displays Amazon product data but the data is not stored in the music database. The shopping cart needs four product attributes: ASIN, Title, Artists, and Price. We have two choices for getting this data: 1) returning to Amazon and repopulating the AmazonItemResponseModel or 2) get the information from the detail page. The first option is easy to code but will be relatively slow because it requires a return trip to Amazon. Therefore we will store the data in hidden form fields in the detail page and send it to the controller when the user clicks the Add To Cart button.
    1. Add hidden form fields to the detail page as shown in the sample (right-click & show source). The value for Asin is @item.ASIN. Other fields are similar syntax.   
    2. The form posts to the action method "AddToCart" which is the next step.
  2. music/cart - Clicking the shopping cart button calls an action method "AddToCart." This handler adds the item to tblCart in the database and displays the Cart view.
    1. Database: The music database needs a new table for storing cart information. Add a table to the Music database named tblCart with the fields shown in the image. This database contains the subset of product information needed for the order.
    2. Model: A model is needed to represent the shopping cart data. Create a new model named MusicCartModel in MusicModels with properties matching the database fields. In C# varchar() fields are type string and float is decimal.
    3. MusicCartRepository: The shopping cart class contains the functionality of a shopping cart: adding items, updating quantities, removing items, listing items, etc. Inside your DataRepository folder create a new class named "MusicCartRepository"  Replace the default code with the source code for the shopping cart. This will add shopping cart functionality to your application as shown in the image. You do not need to make any changes to MusicCartRepository. Shopping Cart class
    4. Controller: Add an action method named AddToCart(MusicCartModel musicCartModel). Instantiate an instance of MusicCartRepository and use its AddToCart method to write item data to the database.  The action method returns View("Cart", musicCartRepository.GetAllItemsInCart()).
    5. The shopping cart uses sessionID to keep track of individual users. By default session ID changes with each request. A non-changing SessionID is created when data is added to the session.  Add the following to Globbal.asax (in root of application). The Session_Start() event fires when a new user makes a request. 
              void Session_Start()
                  Session["stuff"] = "Go Vikings"; 
    6. View: Add a view named Cart. Template is List and model is MusicCartModel.
    7. Test Add To Cart button. The controller should add the item to the database, retrieve all items in the cart, and display the items in cart view.
    8. The user should be able to view the cart without adding anything to it. Add another handler to the controller named "Cart" that displays the items in the cart.
    9. Format the layout of cart with a thumbnail images, add/remove links, link to checkout, etc. See sample site for HTML and CSS. The price totals and shipping are calculated using Razor syntax. Before the foreach loop define a few variables:
          double itemTotal = 0;
          double subTotal = 0;
          int totalQty = 0;
          double discount = 0.8;
          double shippingBase = 3.99;
          double shippingItem = .99;
      Inside the foreach loop calculate values for individual items:
         double price = item.Price / 100 * discount;
         itemTotal = @item.Qty * price;
         subTotal += itemTotal;
         totalQty += @item.Qty;
    10. Controller: The add/remove links in the cart need handlers. Add two more action methods named AddAdditionalItem(string id) and RemoveOneItem(string id). Both methods use musicCartRepository.UpdateCartQty(Asin, XX) where XX is 1 for Add and -1 for Remove.
  3. music/Signin: The checkout process writes customer and order information to the database. It uses three views: signin, checkout, and confirmation. The first view named SignIn gets the customer's email. The HttpPost handler for SignIn checks the database to see if the customer is new or returning and displays the checkout view with an appropriate message. Steps:
    1. tblCustomersModel: Create two new models in MusicModels. The first named SignInModel contains a single Property "Email." Make it required and validate it as a valid email format. See SnowBoardModel for validation syntax.
    2. The second model is named CustomerModel. The model contains the seven properties shown on the checkout page plus custID (see image to right). All properties are string except CustID which is int. Add Required validation to all fields and email validation to email. Add [Key] to CustId so that VS's view-builder puts in into a hidden form field.
    3. Database: Add a table named tblCustomers with fields matching the properties of CustomerModel (see image). CustID the primary key and autonumber (Identity).
    4. Controller: Create an HttpGet ActionResult named SignIn. It does nothing except return an empty view.
    5. View: Create a view named SignIn. Template is Create and model is SignInModel.
    6. Email field should be autofocus. EditorFor statements do not support autofocus so change it to a textbox with:

      @Html.TextBoxFor(model => model.Email, new { @class = "form-control" , autofocus = "autofocus" })

    7. Controller: Clicking the SignIn button posts the form to the HttpPost Signin action method. This method validates the email and redirects to the checkout view. The following shows how to check the validation. 
         public ActionResult SignIn(SignInModel signInModel)
             if (!ModelState.IsValid) return View(signInModel);
      The method then redirects to checkout, passing email as an anonymous object:
           return RedirectToAction("checkout", new { signInModel.Email });
  4. music/checkout - Checkout provides textboxes for customer information. It has two action methods. The first action method queries the database using email to see if the user is new or returning. If returning it will populate the checkout form with user information, otherwise it only populates the email field.  The second action method writes customer information to the database and redirects to the confirmation page.  
    1. MusicRepository: Create a method named GetPersonByEmail(string email) that searches tblCustomers for a matching email and returns a CustomerModel.
    2. Controller: Create an action method named Checkout(string email) and decorate it with a [HttpGet] filter.  This controller depends upon getting an email from signin. Users could potentially arrive at this view without providing an email. Redirect these miscreants back to signin:
      if (email == null) return RedirectToAction("signin");
    3. Query the database using GetPersonByEmail(email) to see if the user is new or returning. Use an if statement to test if a matching email was found. customerModel will be null if a email is not found. For new users we need to instantiate customerModel and add the email address as follows:
         CustomerModel customerModel = musicRepository.GetPersonByEmail(email); 
        if (customerModel != null)
           ViewBag.message = "Returning Customer: Please review shipping information";
            ViewBag.message = "New Customer: Please enter shipping information";
            customerModel = new CustomerModel();
            customerModel.Email = email;
      Finally, return a View containing customerModel.
    4. View: Create a new view "Checkout" that uses the Edit template and CustomerModel. Add a @Viewbag.message tag to display the new/returning customer message.
    5. Test the view.
    6. Controller: Create a HttpPost handler named checkout. This will validate and process the form data.
    7. MusicRepository: The repository needs two additional methods, UpdateCustomer() and InsertCustomer. It is time consuming to these so you may use this code.
    8. In the HttpPost controller use an if statement to determine if the customer is new or returning. Returning customers will have a custID, new customers will not, so we can test custID to determine if new or returning.
              public ActionResult CheckOut(CustomerModel customerModel)
                  if (!ModelState.IsValid) return View(customerModel);
                  //new or returning
                  if (customerModel.CustId > 0)
                     //returning - update database
    9. Complete the code snippet above by calling the update and insert repository methods. The InsertCustomer method returns the autonumber CustID from the database. Assign it to the customerModel as follows:
                      //new customer
                      customerModel.CustId = musicOrderRepository.InsertCustomer(customerModel);
      Note: in A09 you will add code to this action method to write order information.
    10. customer confirmation Finally, the action method returns a view named "OrderConfirmation" with model customerModel. 
      return View("OrderConfirmation", customerModel);
      Also add a message in the ViewBag confirming that the data was written to the database.
    11. Create an view named "OrderConfirmation", template details, model CustomerModel.
    12. Test!
    13. The checkout process will be completed in A09

Submission instructions: Submit assignments via the Canvas course management system. Submit the full URL for each exercise in the assignment, listing the URLs in the same order that they are listed in the assignment. To minimize typos in URLs it is strongly recommended that you copy the URLs from the address bar of the browser rather than trying to type them. Incorrect URLs will not be graded and no credit will be given.

When pages are connected via navigation (as in your music store project) it is only necessary to submit the URL of the first page.

Regular Expressions HTML Color Names Color Picker ASCII Character Codes Unicode Character Codes