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. Anonymous users create 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 - Add a "add to cart" button to the detail page. ASIN is the only parameter needed.
    1. Add to cart links should be visually obvious so that users can find them easily. Most e-commerce sites use colorful images. You may use the image from the sample site or find your own. To copy the button on the sample site right-click on it and select "Save image as..."
    2. The syntax to wrap an image tag with an anchor tag:
       <a href="~/music/addToCart/@item.ASIN">
          <img src="~/Content/images/music/AddCartLarge.jpg" 
                         alt="Add to Cart" class="addToCartLarge" />
  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. Note that item attributes such as title and price do not need to be stored in tblCart since they are in tblDescription.
    2. Model: A model is needed to represent the shopping cart data. Create a new model named MusicCartModel in MusicModels with the following properties. Note that the model includes fields from tblDescription since these attributes are displayed in the cart view.
          public class MusicCartModel
              public string SessionId { get; set; }
              public string ASIN { get; set; }
              public string Title { get; set; }
              public string Artists { get; set; }
              public double ListPrice { get; set; }
              public int Qty { get; set; }
              public DateTime DateAdded { get; set; }
    3. MusicCartRepository: The shopping cart class contains the functionality of a shopping cart: adding items, removing items, listing items, and empty cart. 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: The controller needs three action methods for the cart: Cart (displays the cart), AddToCart, and RemoveFromCart. All three action methods return 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 cart view.
    8. Format cart view with 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:
          //variables with page scope for calculating totals and shipping
          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;
  3. music/Signin: The checkout writes customer and order information to the database. It uses three views: signin, checkout, and confirmation. The SignIn view 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." It is required and should be validated as a valid email format and shown in the answer by Shittu Olugbenga.
    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 action method named SignIn. It does nothing except return an empty view. Decorate it with [HttpGet] action selector.
    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 for the user's 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] action selector.  Users could potentially arrive at this view without providing an email so 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