Udostępnij za pośrednictwem


Koszyk

Autor: Erik Reitan

Pobierz przykładowy projekt Wingtip Toys (C#) lub pobierz książkę elektroniczną (PDF)

W tej serii samouczków przedstawiono podstawy tworzenia aplikacji ASP.NET Web Forms przy użyciu ASP.NET 4.5 i Microsoft Visual Studio Express 2013 for Web. Projekt Visual Studio 2013 z kodem źródłowym języka C# jest dostępny do dołączenia do tej serii samouczków.

W tym samouczku opisano logikę biznesową wymaganą do dodania koszyka zakupów do przykładowej aplikacji Wingtip Toys ASP.NET Web Forms. Ten samouczek opiera się na poprzednim samouczku "Wyświetlanie elementów danych i szczegółów" i jest częścią serii samouczków Wingtip Toy Store. Po ukończeniu tego samouczka użytkownicy przykładowej aplikacji będą mogli dodawać, usuwać i modyfikować produkty w koszyku.

Zawartość:

  1. Jak utworzyć koszyk dla aplikacji internetowej.
  2. Jak umożliwić użytkownikom dodawanie elementów do koszyka.
  3. Jak dodać kontrolkę GridView , aby wyświetlić szczegóły koszyka.
  4. Jak obliczyć i wyświetlić sumę zamówienia.
  5. Jak usunąć i zaktualizować elementy w koszyku.
  6. Jak dołączyć licznik koszyka.

Funkcje kodu w tym samouczku:

  1. Entity Framework Code First
  2. Adnotacje danych
  3. Silnie typizowane kontrolki danych
  4. Powiązanie modelu

Tworzenie koszyka

Wcześniej w tej serii samouczków dodano strony i kod do wyświetlania danych produktów z bazy danych. W tym samouczku utworzysz koszyk do zarządzania produktami, które użytkownicy interesują się zakupem. Użytkownicy będą mogli przeglądać i dodawać elementy do koszyka, nawet jeśli nie są zarejestrowani lub zalogowani. Aby zarządzać dostępem do koszyka zakupów, przypiszesz użytkownikom unikatowy ID identyfikator globalny (GUID), gdy użytkownik uzyskuje dostęp do koszyka po raz pierwszy. Te informacje będą przechowywane ID przy użyciu stanu sesji ASP.NET.

Uwaga

Stan sesji ASP.NET to wygodne miejsce do przechowywania informacji specyficznych dla użytkownika, które wygasną po opuszczeniu witryny przez użytkownika. Chociaż niewłaściwe użycie stanu sesji może mieć wpływ na wydajność większych lokacji, lekkie użycie stanu sesji działa dobrze w celach demonstracyjnych. Przykładowy projekt Wingtip Toys pokazuje, jak używać stanu sesji bez dostawcy zewnętrznego, gdzie stan sesji jest przechowywany w procesie na serwerze internetowym hostujący witrynę. W przypadku większych lokacji, które udostępniają wiele wystąpień aplikacji lub lokacji z wieloma wystąpieniami aplikacji na różnych serwerach, rozważ użycie usługi Windows Azure Cache Service. Ta usługa pamięci podręcznej udostępnia rozproszoną usługę buforowania, która jest zewnętrzna dla witryny sieci Web i rozwiązuje problem z używaniem stanu sesji procesu. Aby uzyskać więcej informacji, zobacz How to Use ASP.NET Session State with Windows Azure Web Sites (Jak używać stanu sesji ASP.NET za pomocą witryn sieci Web platformy Windows Azure).

Dodawanie CartItem jako klasy modelu

Wcześniej w tej serii samouczków zdefiniowano schemat dla kategorii i danych produktu, tworząc Category klasy i Product w folderze Modele . Teraz dodaj nową klasę, aby zdefiniować schemat koszyka. W dalszej części tego samouczka dodasz klasę do obsługi dostępu do danych do CartItem tabeli. Ta klasa zapewni logikę biznesową, aby dodawać, usuwać i aktualizować elementy w koszyku.

  1. Kliknij prawym przyciskiem myszy folder Modele i wybierz polecenie Dodaj ->Nowy element.

    Koszyk zakupów — nowy element

  2. Zostanie wyświetlone okno dialogowe Dodaj nowy element. Wybierz pozycję Kod, a następnie wybierz pozycję Klasa.

    Koszyk — okno dialogowe Dodawanie nowego elementu

  3. Nadaj tej nowej klasie nazwę CartItem.cs.

  4. Kliknij pozycję Dodaj.
    Nowy plik klasy jest wyświetlany w edytorze.

  5. Zastąp kod domyślny następującym kodem:

    using System.ComponentModel.DataAnnotations;
    
    namespace WingtipToys.Models
    {
        public class CartItem
        {
            [Key]
            public string ItemId { get; set; }
    
            public string CartId { get; set; }
    
            public int Quantity { get; set; }
    
            public System.DateTime DateCreated { get; set; }
    
            public int ProductId { get; set; }
    
            public virtual Product Product { get; set; }
    
        }
    }
    

Klasa CartItem zawiera schemat, który zdefiniuje każdy produkt, który użytkownik dodaje do koszyka zakupów. Ta klasa jest podobna do innych klas schematów utworzonych wcześniej w tej serii samouczków. Zgodnie z konwencją kod platformy Entity Framework First oczekuje, że kluczem CartItem podstawowym tabeli będzie albo CartItemIdID. Jednak kod zastępuje domyślne zachowanie przy użyciu atrybutu adnotacji [Key] danych. Atrybut Key właściwości ItemId określa, że ItemID właściwość jest kluczem podstawowym.

Właściwość CartId określa ID użytkownika skojarzonego z elementem do zakupu. Dodasz kod, aby utworzyć tego użytkownika ID , gdy użytkownik uzyskuje dostęp do koszyka. Będzie to ID również przechowywane jako zmienna ASP.NET Sesja.

Aktualizowanie kontekstu produktu

Oprócz dodawania CartItem klasy należy zaktualizować klasę kontekstu bazy danych, która zarządza klasami jednostek i która zapewnia dostęp do danych do bazy danych. W tym celu dodasz nowo utworzoną CartItem klasę ProductContext modelu do klasy.

  1. W Eksplorator rozwiązań znajdź i otwórz plik ProductContext.cs w folderze Models.

  2. Dodaj wyróżniony kod do pliku ProductContext.cs w następujący sposób:

    using System.Data.Entity;
     
    namespace WingtipToys.Models
    {
        public class ProductContext : DbContext
        {
            public ProductContext()
                : base("WingtipToys")
            {
            }
     
            public DbSet<Category> Categories { get; set; }
            public DbSet<Product> Products { get; set; }
            public DbSet<CartItem> ShoppingCartItems { get; set; }
        }
    }
    

Jak wspomniano wcześniej w tej serii samouczków, kod w pliku ProductContext.cs dodaje System.Data.Entity przestrzeń nazw, aby mieć dostęp do wszystkich podstawowych funkcji programu Entity Framework. Ta funkcja obejmuje możliwość wykonywania zapytań, wstawiania, aktualizowania i usuwania danych przez pracę z silnie typizowanymi obiektami. Klasa ProductContext dodaje dostęp do nowo dodanej CartItem klasy modelu.

Zarządzanie logiką biznesową koszyka zakupów

Następnie utworzysz klasę ShoppingCart w nowym folderze logiki . Klasa ShoppingCart obsługuje dostęp do danych do CartItem tabeli. Klasa będzie również zawierać logikę biznesową, aby dodawać, usuwać i aktualizować elementy w koszyku.

Dodana logika koszyka zakupów będzie zawierać funkcje zarządzania następującymi akcjami:

  1. Dodawanie elementów do koszyka
  2. Usuwanie elementów z koszyka
  3. Pobieranie identyfikatora koszyka
  4. Pobieranie elementów z koszyka
  5. Łączna ilość wszystkich elementów koszyka zakupów
  6. Aktualizowanie danych koszyka

Strona koszyka zakupów (ShoppingCart.aspx) i klasa koszyka będą używane razem w celu uzyskania dostępu do danych koszyka. Na stronie koszyka będą wyświetlane wszystkie elementy, które użytkownik dodaje do koszyka. Oprócz strony koszyka i klasy utworzysz stronę (AddToCart.aspx), aby dodać produkty do koszyka. Dodasz również kod do strony ProductList.aspx i strony ProductDetails.aspx , która udostępni link do strony AddToCart.aspx , aby użytkownik mógł dodać produkty do koszyka.

Na poniższym diagramie przedstawiono podstawowy proces, który występuje, gdy użytkownik dodaje produkt do koszyka.

Koszyk — dodawanie do koszyka

Gdy użytkownik kliknie link Dodaj do koszyka na stronie ProductList.aspx lub na stronie ProductDetails.aspx , aplikacja przejdzie do strony AddToCart.aspx , a następnie automatycznie do strony ShoppingCart.aspx . Strona AddToCart.aspx doda wybrany produkt do koszyka, wywołując metodę w klasie ShoppingCart. Na stronie ShoppingCart.aspx zostaną wyświetlone produkty dodane do koszyka.

Tworzenie klasy koszyka zakupów

Klasa ShoppingCart zostanie dodana do oddzielnego folderu w aplikacji, aby istniała wyraźna różnica między modelem (folderem Models), stronami (folderem głównym) i logiką (folder logiki).

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt WingtipToysi wybierz polecenie Dodaj nowy>folder. Nazwij nową logikę folderu.

  2. Kliknij prawym przyciskiem myszy folder Logika , a następnie wybierz polecenie Dodaj ->Nowy element.

  3. Dodaj nowy plik klasy o nazwie ShoppingCartActions.cs.

  4. Zastąp kod domyślny następującym kodem:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using WingtipToys.Models;
    
    namespace WingtipToys.Logic
    {
      public class ShoppingCartActions : IDisposable
      {
        public string ShoppingCartId { get; set; }
    
        private ProductContext _db = new ProductContext();
    
        public const string CartSessionKey = "CartId";
    
        public void AddToCart(int id)
        {
          // Retrieve the product from the database.           
          ShoppingCartId = GetCartId();
    
          var cartItem = _db.ShoppingCartItems.SingleOrDefault(
              c => c.CartId == ShoppingCartId
              && c.ProductId == id);
          if (cartItem == null)
          {
            // Create a new cart item if no cart item exists.                 
            cartItem = new CartItem
            {
              ItemId = Guid.NewGuid().ToString(),
              ProductId = id,
              CartId = ShoppingCartId,
              Product = _db.Products.SingleOrDefault(
               p => p.ProductID == id),
              Quantity = 1,
              DateCreated = DateTime.Now
            };
    
            _db.ShoppingCartItems.Add(cartItem);
          }
          else
          {
            // If the item does exist in the cart,                  
            // then add one to the quantity.                 
            cartItem.Quantity++;
          }
          _db.SaveChanges();
        }
    
        public void Dispose()
        {
          if (_db != null)
          {
            _db.Dispose();
            _db = null;
          }
        }
    
        public string GetCartId()
        {
          if (HttpContext.Current.Session[CartSessionKey] == null)
          {
            if (!string.IsNullOrWhiteSpace(HttpContext.Current.User.Identity.Name))
            {
              HttpContext.Current.Session[CartSessionKey] = HttpContext.Current.User.Identity.Name;
            }
            else
            {
              // Generate a new random GUID using System.Guid class.     
              Guid tempCartId = Guid.NewGuid();
              HttpContext.Current.Session[CartSessionKey] = tempCartId.ToString();
            }
          }
          return HttpContext.Current.Session[CartSessionKey].ToString();
        }
    
        public List<CartItem> GetCartItems()
        {
          ShoppingCartId = GetCartId();
    
          return _db.ShoppingCartItems.Where(
              c => c.CartId == ShoppingCartId).ToList();
        }
      }
    }
    

Metoda AddToCart umożliwia uwzględnianie poszczególnych produktów w koszyku na podstawie produktu ID. Produkt jest dodawany do koszyka lub jeśli koszyk zawiera już element dla tego produktu, ilość jest zwiększana.

Metoda GetCartId zwraca koszyk ID dla użytkownika. ID Koszyk służy do śledzenia elementów, które użytkownik ma w koszyku. Jeśli użytkownik nie ma istniejącego koszyka ID, zostanie utworzony nowy koszyk ID . Jeśli użytkownik jest zalogowany jako zarejestrowany użytkownik, koszyk ID jest ustawiony na nazwę użytkownika. Jeśli jednak użytkownik nie jest zalogowany, koszyk ID jest ustawiony na unikatową wartość (identyfikator GUID). Identyfikator GUID zapewnia utworzenie tylko jednego koszyka dla każdego użytkownika na podstawie sesji.

Metoda GetCartItems zwraca listę elementów koszyka zakupów dla użytkownika. W dalszej części tego samouczka zobaczysz, że powiązanie modelu jest używane do wyświetlania elementów koszyka w koszyku GetCartItems przy użyciu metody .

Tworzenie funkcji dodawania do koszyka

Jak wspomniano wcześniej, utworzysz stronę przetwarzania o nazwie AddToCart.aspx , która będzie używana do dodawania nowych produktów do koszyka zakupów użytkownika. Ta strona wywoła metodę AddToCart w utworzonej ShoppingCart klasie. Strona AddToCart.aspx będzie oczekiwać, że produkt ID zostanie przekazany do niego. Ten produkt ID będzie używany podczas wywoływania AddToCart metody w ShoppingCart klasie .

Uwaga

Będziesz modyfikować kod-behind (AddToCart.aspx.cs) dla tej strony, a nie interfejs użytkownika strony (AddToCart.aspx).

Aby utworzyć funkcję Add-To-Cart:

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt WingtipToys, kliknij pozycję Dodaj ->Nowy element.
    Zostanie wyświetlone okno dialogowe Dodaj nowy element.

  2. Dodaj standardową nową stronę (formularz internetowy) do aplikacji o nazwie AddToCart.aspx.

    Koszyk zakupów — dodawanie formularza internetowego

  3. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy stronę AddToCart.aspx, a następnie kliknij pozycję Wyświetl kod. Plik AddToCart.aspx.cs code-behind jest otwierany w edytorze.

  4. Zastąp istniejący kod w kodzie AddToCart.aspx.cs następującym kodem:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Diagnostics;
    using WingtipToys.Logic;
    
    namespace WingtipToys
    {
      public partial class AddToCart : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          string rawId = Request.QueryString["ProductID"];
          int productId;
          if (!String.IsNullOrEmpty(rawId) && int.TryParse(rawId, out productId))
          {
            using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
            {
              usersShoppingCart.AddToCart(Convert.ToInt16(rawId));
            }
    
          }
          else
          {
            Debug.Fail("ERROR : We should never get to AddToCart.aspx without a ProductId.");
            throw new Exception("ERROR : It is illegal to load AddToCart.aspx without setting a ProductId.");
          }
          Response.Redirect("ShoppingCart.aspx");
        }
      }
    }
    

Po załadowaniu strony AddToCart.aspx produkt ID zostanie pobrany z ciągu zapytania. Następnie zostanie utworzone wystąpienie klasy koszyka zakupów i zostanie użyte do wywołania AddToCart metody dodanej wcześniej w tym samouczku. Metoda AddToCart zawarta w pliku ShoppingCartActions.cs zawiera logikę dodawania wybranego produktu do koszyka zakupów lub zwiększa ilość produktu wybranego produktu. Jeśli produkt nie został dodany do koszyka, produkt zostanie dodany do CartItem tabeli bazy danych. Jeśli produkt został już dodany do koszyka, a użytkownik dodaje dodatkowy element tego samego produktu, ilość produktu jest zwiększana w CartItem tabeli. Na koniec strona przekierowuje z powrotem do strony ShoppingCart.aspx , którą dodasz w następnym kroku, gdzie użytkownik widzi zaktualizowaną listę elementów w koszyku.

Jak wspomniano wcześniej, użytkownik ID jest używany do identyfikowania produktów skojarzonych z określonym użytkownikiem. Jest to ID dodawane do wiersza w CartItem tabeli za każdym razem, gdy użytkownik dodaje produkt do koszyka.

Tworzenie interfejsu użytkownika koszyka zakupów

Na stronie ShoppingCart.aspx zostaną wyświetlone produkty dodane przez użytkownika do koszyka. Zapewni również możliwość dodawania, usuwania i aktualizowania elementów w koszyku.

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy pozycję WingtipToys, kliknij pozycję Dodaj ->Nowy element.
    Zostanie wyświetlone okno dialogowe Dodaj nowy element.

  2. Dodaj nową stronę (formularz internetowy), która zawiera stronę wzorcową, wybierając pozycję Formularz internetowy przy użyciu strony wzorcowej. Nadaj nowej stronie nazwę ShoppingCart.aspx.

  3. Wybierz pozycję Site.Master, aby dołączyć stronę wzorcową do nowo utworzonej strony aspx .

  4. Na stronie ShoppingCart.aspx zastąp istniejący znacznik następującym znacznikiem:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ShoppingCart.aspx.cs" Inherits="WingtipToys.ShoppingCart" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <div id="ShoppingCartTitle" runat="server" class="ContentHead"><h1>Shopping Cart</h1></div>
        <asp:GridView ID="CartList" runat="server" AutoGenerateColumns="False" ShowFooter="True" GridLines="Vertical" CellPadding="4"
            ItemType="WingtipToys.Models.CartItem" SelectMethod="GetShoppingCartItems" 
            CssClass="table table-striped table-bordered" >   
            <Columns>
            <asp:BoundField DataField="ProductID" HeaderText="ID" SortExpression="ProductID" />        
            <asp:BoundField DataField="Product.ProductName" HeaderText="Name" />        
            <asp:BoundField DataField="Product.UnitPrice" HeaderText="Price (each)" DataFormatString="{0:c}"/>     
            <asp:TemplateField   HeaderText="Quantity">            
                    <ItemTemplate>
                        <asp:TextBox ID="PurchaseQuantity" Width="40" runat="server" Text="<%#: Item.Quantity %>"></asp:TextBox> 
                    </ItemTemplate>        
            </asp:TemplateField>    
            <asp:TemplateField HeaderText="Item Total">            
                    <ItemTemplate>
                        <%#: String.Format("{0:c}", ((Convert.ToDouble(Item.Quantity)) *  Convert.ToDouble(Item.Product.UnitPrice)))%>
                    </ItemTemplate>        
            </asp:TemplateField> 
            <asp:TemplateField HeaderText="Remove Item">            
                    <ItemTemplate>
                        <asp:CheckBox id="Remove" runat="server"></asp:CheckBox>
                    </ItemTemplate>        
            </asp:TemplateField>    
            </Columns>    
        </asp:GridView>
        <div>
            <p></p>
            <strong>
                <asp:Label ID="LabelTotalText" runat="server" Text="Order Total: "></asp:Label>
                <asp:Label ID="lblTotal" runat="server" EnableViewState="false"></asp:Label>
            </strong> 
        </div>
        <br />
    </asp:Content>
    

Strona ShoppingCart.aspx zawiera kontrolkę GridView o nazwie CartList. Ta kontrolka używa powiązania modelu, aby powiązać dane koszyka z bazy danych z kontrolką GridView . Po ustawieniu ItemType właściwości kontrolki GridView wyrażenie Item powiązania danych jest dostępne w znacznikach kontrolki, a kontrolka staje się silnie typizowana. Jak wspomniano wcześniej w tej serii samouczków Item , możesz wybrać szczegóły obiektu przy użyciu funkcji IntelliSense. Aby skonfigurować kontrolkę danych do używania powiązania modelu do wybierania danych, należy ustawić SelectMethod właściwość kontrolki. W powyższym adiustacji ustawiono SelectMethod metodę GetShoppingCartItems, która zwraca listę CartItem obiektów. Kontrolka danych GridView wywołuje metodę w odpowiednim czasie w cyklu życia strony i automatycznie wiąże zwrócone dane. Metoda GetShoppingCartItems musi być nadal dodawana.

Pobieranie elementów koszyka

Następnie dodasz kod do pliku ShoppingCart.aspx.cs code-behind, aby pobrać i wypełnić interfejs użytkownika koszyka zakupów.

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy stronę ShoppingCart.aspx, a następnie kliknij pozycję Wyświetl kod. Plik ShoppingCart.aspx.cs code-behind jest otwierany w edytorze.

  2. Zastąp istniejący kod następującym kodem:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using WingtipToys.Models;
    using WingtipToys.Logic;
    
    namespace WingtipToys
    {
      public partial class ShoppingCart : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
    
        }
    
        public List<CartItem> GetShoppingCartItems()
        {
          ShoppingCartActions actions = new ShoppingCartActions();
          return actions.GetCartItems();
        }
      }
    }
    

Jak wspomniano powyżej, kontrolka GridView danych wywołuje metodę GetShoppingCartItems w odpowiednim czasie w cyklu życia strony i automatycznie wiąże zwrócone dane. Metoda GetShoppingCartItems tworzy wystąpienie ShoppingCartActions obiektu. Następnie kod używa tego wystąpienia do zwrócenia elementów w koszyku przez wywołanie GetCartItems metody .

Dodawanie produktów do koszyka

Gdy zostanie wyświetlona strona ProductList.aspx lub ProductDetails.aspx , użytkownik będzie mógł dodać produkt do koszyka przy użyciu linku. Po kliknięciu linku aplikacja przechodzi do strony przetwarzania o nazwie AddToCart.aspx. Strona AddToCart.aspx wywoła metodę AddToCart w klasie dodanej ShoppingCart wcześniej w tym samouczku.

Teraz dodasz link Dodaj do koszyka do strony ProductList.aspx i strony ProductDetails.aspx . Ten link będzie zawierać produkt ID pobrany z bazy danych.

  1. W Eksplorator rozwiązań znajdź i otwórz stronę o nazwie ProductList.aspx.

  2. Dodaj znacznik wyróżniony kolorem żółtym do strony ProductList.aspx , aby cała strona pojawiła się w następujący sposób:

    <%@ Page Title="Products" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" 
             CodeBehind="ProductList.aspx.cs" Inherits="WingtipToys.ProductList" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <section>
            <div>
                <hgroup>
                    <h2><%: Page.Title %></h2>
                </hgroup>
    
                <asp:ListView ID="productList" runat="server" 
                    DataKeyNames="ProductID" GroupItemCount="4"
                    ItemType="WingtipToys.Models.Product" SelectMethod="GetProducts">
                    <EmptyDataTemplate>
                        <table runat="server">
                            <tr>
                                <td>No data was returned.</td>
                            </tr>
                        </table>
                    </EmptyDataTemplate>
                    <EmptyItemTemplate>
                        <td runat="server" />
                    </EmptyItemTemplate>
                    <GroupTemplate>
                        <tr id="itemPlaceholderContainer" runat="server">
                            <td id="itemPlaceholder" runat="server"></td>
                        </tr>
                    </GroupTemplate>
                    <ItemTemplate>
                        <td runat="server">
                            <table>
                                <tr>
                                    <td>
                                        <a href="ProductDetails.aspx?productID=<%#:Item.ProductID%>">
                                            <img src="/Catalog/Images/Thumbs/<%#:Item.ImagePath%>"
                                                width="100" height="75" style="border: solid" /></a>
                                    </td>
                                </tr>
                                <tr>
                                    <td>
                                        <a href="ProductDetails.aspx?productID=<%#:Item.ProductID%>">
                                            <span>
                                                <%#:Item.ProductName%>
                                            </span>
                                        </a>
                                        <br />
                                        <span>
                                            <b>Price: </b><%#:String.Format("{0:c}", Item.UnitPrice)%>
                                        </span>
                                        <br />
                                        <a href="/AddToCart.aspx?productID=<%#:Item.ProductID %>">               
                                            <span class="ProductListItem">
                                                <b>Add To Cart<b>
                                            </span>           
                                        </a>
                                    </td>
                                </tr>
                                <tr>
                                    <td>&nbsp;</td>
                                </tr>
                            </table>
                            </p>
                        </td>
                    </ItemTemplate>
                    <LayoutTemplate>
                        <table runat="server" style="width:100%;">
                            <tbody>
                                <tr runat="server">
                                    <td runat="server">
                                        <table id="groupPlaceholderContainer" runat="server" style="width:100%">
                                            <tr id="groupPlaceholder" runat="server"></tr>
                                        </table>
                                    </td>
                                </tr>
                                <tr runat="server">
                                    <td runat="server"></td>
                                </tr>
                                <tr></tr>
                            </tbody>
                        </table>
                    </LayoutTemplate>
                </asp:ListView>
            </div>
        </section>
    </asp:Content>
    

Testowanie koszyka

Uruchom aplikację, aby zobaczyć, jak dodawać produkty do koszyka.

  1. Naciśnij klawisz F5 , aby uruchomić aplikację.
    Po ponownym utworzeniu bazy danych w przeglądarce zostanie otwarta strona Default.aspx .

  2. Wybierz pozycję Samochody z menu nawigacji kategorii.
    Na stronie ProductList.aspx są wyświetlane tylko produkty uwzględnione w kategorii "Samochody".

    Koszyk na zakupy — samochody

  3. Kliknij link Dodaj do koszyka obok pierwszego produktu na liście (samochód kabrioletowy).
    Zostanie wyświetlona strona ShoppingCart.aspx z wyborem w koszyku.

    Koszyk zakupów — koszyk

  4. Wyświetl dodatkowe produkty, wybierając pozycję Płaszczyzny z menu nawigacji kategorii.

  5. Kliknij link Dodaj do koszyka obok pierwszego produktu.
    Strona ShoppingCart.aspx jest wyświetlana z dodatkowym elementem.

  6. Zamknij okno przeglądarki.

Obliczanie i wyświetlanie sumy zamówienia

Oprócz dodawania produktów do koszyka, dodasz metodę do ShoppingCart klasy i wyświetlisz łączną GetTotal kwotę zamówienia na stronie koszyka.

  1. W Eksplorator rozwiązań otwórz plik ShoppingCartActions.cs w folderze Logika.

  2. Dodaj następującą GetTotal metodę wyróżnioną kolorem żółtym ShoppingCart do klasy, aby klasa wyglądała następująco:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using WingtipToys.Models;
    
    namespace WingtipToys.Logic
    {
      public class ShoppingCartActions : IDisposable
      {
        public string ShoppingCartId { get; set; }
    
        private ProductContext _db = new ProductContext();
    
        public const string CartSessionKey = "CartId";
    
        public void AddToCart(int id)
        {
          // Retrieve the product from the database.           
          ShoppingCartId = GetCartId();
    
          var cartItem = _db.ShoppingCartItems.SingleOrDefault(
              c => c.CartId == ShoppingCartId
              && c.ProductId == id);
          if (cartItem == null)
          {
            // Create a new cart item if no cart item exists.                 
            cartItem = new CartItem
            {
              ItemId = Guid.NewGuid().ToString(),
              ProductId = id,
              CartId = ShoppingCartId,
              Product = _db.Products.SingleOrDefault(
               p => p.ProductID == id),
              Quantity = 1,
              DateCreated = DateTime.Now
            };
    
            _db.ShoppingCartItems.Add(cartItem);
          }
          else
          {
            // If the item does exist in the cart,                  
            // then add one to the quantity.                 
            cartItem.Quantity++;
          }
          _db.SaveChanges();
        }
    
        public void Dispose()
        {
          if (_db != null)
          {
            _db.Dispose();
            _db = null;
          }
        }
    
        public string GetCartId()
        {
          if (HttpContext.Current.Session[CartSessionKey] == null)
          {
            if (!string.IsNullOrWhiteSpace(HttpContext.Current.User.Identity.Name))
            {
              HttpContext.Current.Session[CartSessionKey] = HttpContext.Current.User.Identity.Name;
            }
            else
            {
              // Generate a new random GUID using System.Guid class.     
              Guid tempCartId = Guid.NewGuid();
              HttpContext.Current.Session[CartSessionKey] = tempCartId.ToString();
            }
          }
          return HttpContext.Current.Session[CartSessionKey].ToString();
        }
    
        public List<CartItem> GetCartItems()
        {
          ShoppingCartId = GetCartId();
    
          return _db.ShoppingCartItems.Where(
              c => c.CartId == ShoppingCartId).ToList();
        }
    
        public decimal GetTotal()
        {
          ShoppingCartId = GetCartId();
          // Multiply product price by quantity of that product to get        
          // the current price for each of those products in the cart.  
          // Sum all product price totals to get the cart total.   
          decimal? total = decimal.Zero;
          total = (decimal?)(from cartItems in _db.ShoppingCartItems
                             where cartItems.CartId == ShoppingCartId
                             select (int?)cartItems.Quantity *
                             cartItems.Product.UnitPrice).Sum();
          return total ?? decimal.Zero;
        }
      }
    }
    

GetTotal Najpierw metoda pobiera identyfikator koszyka zakupów dla użytkownika. Następnie metoda pobiera sumę koszyka przez pomnożenie ceny produktu według ilości produktu dla każdego produktu wymienionego w koszyku.

Uwaga

Powyższy kod używa typu null "int?". Typy dopuszczane do wartości null mogą reprezentować wszystkie wartości typu bazowego, a także jako wartość null. Aby uzyskać więcej informacji, zobacz Używanie typów dopuszczanych do wartości null.

Modyfikowanie wyświetlania koszyka zakupów

Następnie zmodyfikujesz kod strony ShoppingCart.aspx , aby wywołać metodę GetTotal i wyświetlić tę sumę na stronie ShoppingCart.aspx podczas ładowania strony.

  1. W Eksplorator rozwiązań kliknij prawym przyciskiem myszy stronę ShoppingCart.aspx i wybierz pozycję Wyświetl kod.

  2. W pliku ShoppingCart.aspx.cs zaktualizuj Page_Load program obsługi, dodając następujący kod wyróżniony kolorem żółtym:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using WingtipToys.Models;
    using WingtipToys.Logic;
    
    namespace WingtipToys
    {
      public partial class ShoppingCart : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
          {
            decimal cartTotal = 0;
            cartTotal = usersShoppingCart.GetTotal();
            if (cartTotal > 0)
            {
              // Display Total.
              lblTotal.Text = String.Format("{0:c}", cartTotal);
            }
            else
            {
              LabelTotalText.Text = "";
              lblTotal.Text = "";
              ShoppingCartTitle.InnerText = "Shopping Cart is Empty";
            }
          }
        }
    
        public List<CartItem> GetShoppingCartItems()
        {
          ShoppingCartActions actions = new ShoppingCartActions();
          return actions.GetCartItems();
        }
      }
    }
    

Gdy strona ShoppingCart.aspx zostanie załadowana, ładuje obiekt koszyka zakupów, a następnie pobiera sumę koszyka, wywołując GetTotal metodę ShoppingCart klasy. Jeśli koszyk jest pusty, zostanie wyświetlony komunikat z tym efektem.

Testowanie sumy koszyka

Uruchom aplikację teraz, aby zobaczyć, jak można nie tylko dodać produkt do koszyka, ale zobaczyć sumę koszyka.

  1. Naciśnij klawisz F5 , aby uruchomić aplikację.
    Przeglądarka zostanie otwarta i zostanie wyświetlona strona Default.aspx .

  2. Wybierz pozycję Samochody z menu nawigacji kategorii.

  3. Kliknij link Dodaj do koszyka obok pierwszego produktu.
    Strona ShoppingCart.aspx jest wyświetlana z sumą zamówienia.

    Koszyk — łączna liczba koszyków

  4. Dodaj inne produkty (na przykład samolot) do koszyka.

  5. Strona ShoppingCart.aspx jest wyświetlana ze zaktualizowaną sumą dla wszystkich dodanych produktów.

    Koszyk na zakupy — wiele produktów

  6. Zatrzymaj uruchomioną aplikację, zamykając okno przeglądarki.

Dodawanie przycisków aktualizacji i wyewidencjonowania do koszyka

Aby umożliwić użytkownikom modyfikowanie koszyka, do strony koszyka dodasz przycisk Aktualizuj i przycisk Wyewidencjonuj . Przycisk Wyewidencjonuj nie jest używany do dalszej części tej serii samouczków.

  1. W Eksplorator rozwiązań otwórz stronę ShoppingCart.aspx w katalogu głównym projektu aplikacji internetowej.

  2. Aby dodać przycisk Aktualizuj i przycisk Wyewidencjonuj na stronie ShoppingCart.aspx , dodaj znacznik wyróżniony kolorem żółtym do istniejącego znacznika, jak pokazano w poniższym kodzie:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="ShoppingCart.aspx.cs" Inherits="WingtipToys.ShoppingCart" %>
    <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
        <div id="ShoppingCartTitle" runat="server" class="ContentHead"><h1>Shopping Cart</h1></div>
        <asp:GridView ID="CartList" runat="server" AutoGenerateColumns="False" ShowFooter="True" GridLines="Vertical" CellPadding="4"
            ItemType="WingtipToys.Models.CartItem" SelectMethod="GetShoppingCartItems"  
            CssClass="table table-striped table-bordered" >   
            <Columns>
            <asp:BoundField DataField="ProductID" HeaderText="ID" SortExpression="ProductID" />        
            <asp:BoundField DataField="Product.ProductName" HeaderText="Name" />        
            <asp:BoundField DataField="Product.UnitPrice" HeaderText="Price (each)" DataFormatString="{0:c}"/>     
            <asp:TemplateField   HeaderText="Quantity">            
                    <ItemTemplate>
                        <asp:TextBox ID="PurchaseQuantity" Width="40" runat="server" Text="<%#: Item.Quantity %>"></asp:TextBox> 
                    </ItemTemplate>        
            </asp:TemplateField>    
            <asp:TemplateField HeaderText="Item Total">            
                    <ItemTemplate>
                        <%#: String.Format("{0:c}", ((Convert.ToDouble(Item.Quantity)) *  Convert.ToDouble(Item.Product.UnitPrice)))%>
                    </ItemTemplate>        
            </asp:TemplateField> 
            <asp:TemplateField HeaderText="Remove Item">            
                    <ItemTemplate>
                        <asp:CheckBox id="Remove" runat="server"></asp:CheckBox>
                    </ItemTemplate>        
            </asp:TemplateField>    
            </Columns>    
        </asp:GridView>
        <div>
            <p></p>
            <strong>
                <asp:Label ID="LabelTotalText" runat="server" Text="Order Total: "></asp:Label>
                <asp:Label ID="lblTotal" runat="server" EnableViewState="false"></asp:Label>
            </strong> 
        </div>
      <br />
        <table> 
        <tr>
          <td>
            <asp:Button ID="UpdateBtn" runat="server" Text="Update" OnClick="UpdateBtn_Click" />
          </td>
          <td>
            <!--Checkout Placeholder -->
          </td>
        </tr>
        </table>
    </asp:Content>
    

Gdy użytkownik kliknie przycisk Aktualizuj , UpdateBtn_Click zostanie wywołana procedura obsługi zdarzeń. Ta procedura obsługi zdarzeń wywoła kod, który zostanie dodany w następnym kroku.

Następnie możesz zaktualizować kod zawarty w pliku ShoppingCart.aspx.cs w celu pętli przez elementy koszyka i wywołać RemoveItem metody i UpdateItem .

  1. W Eksplorator rozwiązań otwórz plik ShoppingCart.aspx.cs w katalogu głównym projektu aplikacji internetowej.

  2. Dodaj następujące sekcje kodu wyróżnione kolorem żółtym do pliku ShoppingCart.aspx.cs :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using WingtipToys.Models;
    using WingtipToys.Logic;
    using System.Collections.Specialized;
    using System.Collections;
    using System.Web.ModelBinding;
    
    namespace WingtipToys
    {
      public partial class ShoppingCart : System.Web.UI.Page
      {
        protected void Page_Load(object sender, EventArgs e)
        {
          using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
          {
            decimal cartTotal = 0;
            cartTotal = usersShoppingCart.GetTotal();
            if (cartTotal > 0)
            {
              // Display Total.
              lblTotal.Text = String.Format("{0:c}", cartTotal);
            }
            else
            {
              LabelTotalText.Text = "";
              lblTotal.Text = "";
              ShoppingCartTitle.InnerText = "Shopping Cart is Empty";
              UpdateBtn.Visible = false;
            }
          }
        }
    
        public List<CartItem> GetShoppingCartItems()
        {
          ShoppingCartActions actions = new ShoppingCartActions();
          return actions.GetCartItems();
        }
    
        public List<CartItem> UpdateCartItems()
        {
          using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
          {
            String cartId = usersShoppingCart.GetCartId();
    
            ShoppingCartActions.ShoppingCartUpdates[] cartUpdates = new ShoppingCartActions.ShoppingCartUpdates[CartList.Rows.Count];
            for (int i = 0; i < CartList.Rows.Count; i++)
            {
              IOrderedDictionary rowValues = new OrderedDictionary();
              rowValues = GetValues(CartList.Rows[i]);
              cartUpdates[i].ProductId = Convert.ToInt32(rowValues["ProductID"]);
    
              CheckBox cbRemove = new CheckBox();
              cbRemove = (CheckBox)CartList.Rows[i].FindControl("Remove");
              cartUpdates[i].RemoveItem = cbRemove.Checked;
    
              TextBox quantityTextBox = new TextBox();
              quantityTextBox = (TextBox)CartList.Rows[i].FindControl("PurchaseQuantity");
              cartUpdates[i].PurchaseQuantity = Convert.ToInt16(quantityTextBox.Text.ToString());
            }
            usersShoppingCart.UpdateShoppingCartDatabase(cartId, cartUpdates);
            CartList.DataBind();
            lblTotal.Text = String.Format("{0:c}", usersShoppingCart.GetTotal());
            return usersShoppingCart.GetCartItems();
          }
        }
    
        public static IOrderedDictionary GetValues(GridViewRow row)
        {
          IOrderedDictionary values = new OrderedDictionary();
          foreach (DataControlFieldCell cell in row.Cells)
          {
            if (cell.Visible)
            {
              // Extract values from the cell.
              cell.ContainingField.ExtractValuesFromCell(values, cell, row.RowState, true);
            }
          }
          return values;
        }
    
        protected void UpdateBtn_Click(object sender, EventArgs e)
        {
          UpdateCartItems();
        }
      }
    }
    

Gdy użytkownik kliknie przycisk Aktualizuj na stronie ShoppingCart.aspx , wywoływana jest metoda UpdateCartItems. Metoda UpdateCartItems pobiera zaktualizowane wartości dla każdego elementu w koszyku. Następnie metoda UpdateCartItems wywołuje metodę UpdateShoppingCartDatabase (dodano i wyjaśniono w następnym kroku), aby dodać lub usunąć elementy z koszyka. Po zaktualizowaniu bazy danych w celu odzwierciedlenia aktualizacji koszyka kontrolka GridView zostanie zaktualizowana na stronie koszyka zakupów przez wywołanie DataBind metody GridView. Ponadto łączna kwota zamówienia na stronie koszyka jest aktualizowana w celu odzwierciedlenia zaktualizowanej listy elementów.

Aktualizowanie i usuwanie elementów koszyka

Na stronie ShoppingCart.aspx można zobaczyć, że kontrolki zostały dodane do aktualizowania ilości elementu i usuwania elementu. Teraz dodaj kod, który sprawi, że te kontrolki będą działać.

  1. W Eksplorator rozwiązań otwórz plik ShoppingCartActions.cs w folderze Logika.

  2. Dodaj następujący kod wyróżniony kolorem żółtym do pliku klasy ShoppingCartActions.cs :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using WingtipToys.Models;
    
    namespace WingtipToys.Logic
    {
      public class ShoppingCartActions : IDisposable
      {
        public string ShoppingCartId { get; set; }
    
        private ProductContext _db = new ProductContext();
    
        public const string CartSessionKey = "CartId";
    
        public void AddToCart(int id)
        {
          // Retrieve the product from the database.           
          ShoppingCartId = GetCartId();
    
          var cartItem = _db.ShoppingCartItems.SingleOrDefault(
              c => c.CartId == ShoppingCartId
              && c.ProductId == id);
          if (cartItem == null)
          {
            // Create a new cart item if no cart item exists.                 
            cartItem = new CartItem
            {
              ItemId = Guid.NewGuid().ToString(),
              ProductId = id,
              CartId = ShoppingCartId,
              Product = _db.Products.SingleOrDefault(
               p => p.ProductID == id),
              Quantity = 1,
              DateCreated = DateTime.Now
            };
    
            _db.ShoppingCartItems.Add(cartItem);
          }
          else
          {
            // If the item does exist in the cart,                  
            // then add one to the quantity.                 
            cartItem.Quantity++;
          }
          _db.SaveChanges();
        }
    
        public void Dispose()
        {
          if (_db != null)
          {
            _db.Dispose();
            _db = null;
          }
        }
    
        public string GetCartId()
        {
          if (HttpContext.Current.Session[CartSessionKey] == null)
          {
            if (!string.IsNullOrWhiteSpace(HttpContext.Current.User.Identity.Name))
            {
              HttpContext.Current.Session[CartSessionKey] = HttpContext.Current.User.Identity.Name;
            }
            else
            {
              // Generate a new random GUID using System.Guid class.     
              Guid tempCartId = Guid.NewGuid();
              HttpContext.Current.Session[CartSessionKey] = tempCartId.ToString();
            }
          }
          return HttpContext.Current.Session[CartSessionKey].ToString();
        }
    
        public List<CartItem> GetCartItems()
        {
          ShoppingCartId = GetCartId();
    
          return _db.ShoppingCartItems.Where(
              c => c.CartId == ShoppingCartId).ToList();
        }
    
        public decimal GetTotal()
        {
          ShoppingCartId = GetCartId();
          // Multiply product price by quantity of that product to get        
          // the current price for each of those products in the cart.  
          // Sum all product price totals to get the cart total.   
          decimal? total = decimal.Zero;
          total = (decimal?)(from cartItems in _db.ShoppingCartItems
                             where cartItems.CartId == ShoppingCartId
                             select (int?)cartItems.Quantity *
                             cartItems.Product.UnitPrice).Sum();
          return total ?? decimal.Zero;
        }
    
        public ShoppingCartActions GetCart(HttpContext context)
        {
          using (var cart = new ShoppingCartActions())
          {
            cart.ShoppingCartId = cart.GetCartId();
            return cart;
          }
        }
    
        public void UpdateShoppingCartDatabase(String cartId, ShoppingCartUpdates[] CartItemUpdates)
        {
          using (var db = new WingtipToys.Models.ProductContext())
          {
            try
            {
              int CartItemCount = CartItemUpdates.Count();
              List<CartItem> myCart = GetCartItems();
              foreach (var cartItem in myCart)
              {
                // Iterate through all rows within shopping cart list
                for (int i = 0; i < CartItemCount; i++)
                {
                  if (cartItem.Product.ProductID == CartItemUpdates[i].ProductId)
                  {
                    if (CartItemUpdates[i].PurchaseQuantity < 1 || CartItemUpdates[i].RemoveItem == true)
                    {
                      RemoveItem(cartId, cartItem.ProductId);
                    }
                    else
                    {
                      UpdateItem(cartId, cartItem.ProductId, CartItemUpdates[i].PurchaseQuantity);
                    }
                  }
                }
              }
            }
            catch (Exception exp)
            {
              throw new Exception("ERROR: Unable to Update Cart Database - " + exp.Message.ToString(), exp);
            }
          }
        }
    
        public void RemoveItem(string removeCartID, int removeProductID)
        {
          using (var _db = new WingtipToys.Models.ProductContext())
          {
            try
            {
              var myItem = (from c in _db.ShoppingCartItems where c.CartId == removeCartID && c.Product.ProductID == removeProductID select c).FirstOrDefault();
              if (myItem != null)
              {
                // Remove Item.
                _db.ShoppingCartItems.Remove(myItem);
                _db.SaveChanges();
              }
            }
            catch (Exception exp)
            {
              throw new Exception("ERROR: Unable to Remove Cart Item - " + exp.Message.ToString(), exp);
            }
          }
        }
    
        public void UpdateItem(string updateCartID, int updateProductID, int quantity)
        {
          using (var _db = new WingtipToys.Models.ProductContext())
          {
            try
            {
              var myItem = (from c in _db.ShoppingCartItems where c.CartId == updateCartID && c.Product.ProductID == updateProductID select c).FirstOrDefault();
              if (myItem != null)
              {
                myItem.Quantity = quantity;
                _db.SaveChanges();
              }
            }
            catch (Exception exp)
            {
              throw new Exception("ERROR: Unable to Update Cart Item - " + exp.Message.ToString(), exp);
            }
          }
        }
    
        public void EmptyCart()
        {
          ShoppingCartId = GetCartId();
          var cartItems = _db.ShoppingCartItems.Where(
              c => c.CartId == ShoppingCartId);
          foreach (var cartItem in cartItems)
          {
            _db.ShoppingCartItems.Remove(cartItem);
          }
          // Save changes.             
          _db.SaveChanges();
        }
    
        public int GetCount()
        {
          ShoppingCartId = GetCartId();
    
          // Get the count of each item in the cart and sum them up          
          int? count = (from cartItems in _db.ShoppingCartItems
                        where cartItems.CartId == ShoppingCartId
                        select (int?)cartItems.Quantity).Sum();
          // Return 0 if all entries are null         
          return count ?? 0;
        }
    
        public struct ShoppingCartUpdates
        {
          public int ProductId;
          public int PurchaseQuantity;
          public bool RemoveItem;
        }
      }
    }
    

Metoda UpdateShoppingCartDatabase wywoływana z UpdateCartItems metody na stronie ShoppingCart.aspx.cs zawiera logikę aktualizowania lub usuwania elementów z koszyka. Metoda UpdateShoppingCartDatabase iteruje wszystkie wiersze na liście koszyków. Jeśli element koszyka zakupów został oznaczony jako usunięty lub ilość jest mniejsza niż jedna, RemoveItem wywoływana jest metoda . W przeciwnym razie element koszyka jest sprawdzany pod kątem aktualizacji po wywołaniu UpdateItem metody. Po usunięciu lub zaktualizowaniu elementu koszyka zostaną zapisane zmiany bazy danych.

Struktura ShoppingCartUpdates jest używana do przechowywania wszystkich przedmiotów koszyka zakupów. Metoda UpdateShoppingCartDatabase używa ShoppingCartUpdates struktury do określenia, czy którykolwiek z elementów musi zostać zaktualizowany lub usunięty.

W następnym samouczku użyjesz EmptyCart metody , aby wyczyścić koszyk po zakupie produktów. Jednak na razie użyjesz GetCount metody, która właśnie została dodana do pliku ShoppingCartActions.cs , aby określić liczbę elementów w koszyku.

Dodawanie licznika koszyka zakupów

Aby zezwolić użytkownikowi na wyświetlanie całkowitej liczby elementów w koszyku, dodaj licznik do strony Site.Master . Ten licznik będzie również działać jako link do koszyka zakupów.

  1. W Eksplorator rozwiązań otwórz stronę Site.Master.

  2. Zmodyfikuj znaczniki, dodając link licznika koszyka zakupów, jak pokazano w kolorze żółtym do sekcji nawigacji, aby wyglądała następująco:

    <ul class="nav navbar-nav">
          <li><a runat="server" href="~/">Home</a></li>
          <li><a runat="server" href="~/About">About</a></li>
          <li><a runat="server" href="~/Contact">Contact</a></li>
          <li><a runat="server" href="~/ProductList">Products</a></li>
          <li><a runat="server" href="~/ShoppingCart" ID="cartCount">&nbsp;</a></li>
      </ul>
    
  3. Następnie zaktualizuj kod pliku Site.Master.cs , dodając kod wyróżniony kolorem żółtym w następujący sposób:

    using System;
    using System.Collections.Generic;
    using System.Security.Claims;
    using System.Security.Principal;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Linq;
    using WingtipToys.Models;
    using WingtipToys.Logic;
    
    namespace WingtipToys
    {
        public partial class SiteMaster : MasterPage
        {
            private const string AntiXsrfTokenKey = "__AntiXsrfToken";
            private const string AntiXsrfUserNameKey = "__AntiXsrfUserName";
            private string _antiXsrfTokenValue;
    
            protected void Page_Init(object sender, EventArgs e)
            {
                // The code below helps to protect against XSRF attacks
                var requestCookie = Request.Cookies[AntiXsrfTokenKey];
                Guid requestCookieGuidValue;
                if (requestCookie != null && Guid.TryParse(requestCookie.Value, out requestCookieGuidValue))
                {
                    // Use the Anti-XSRF token from the cookie
                    _antiXsrfTokenValue = requestCookie.Value;
                    Page.ViewStateUserKey = _antiXsrfTokenValue;
                }
                else
                {
                    // Generate a new Anti-XSRF token and save to the cookie
                    _antiXsrfTokenValue = Guid.NewGuid().ToString("N");
                    Page.ViewStateUserKey = _antiXsrfTokenValue;
    
                    var responseCookie = new HttpCookie(AntiXsrfTokenKey)
                    {
                        HttpOnly = true,
                        Value = _antiXsrfTokenValue
                    };
                    if (FormsAuthentication.RequireSSL && Request.IsSecureConnection)
                    {
                        responseCookie.Secure = true;
                    }
                    Response.Cookies.Set(responseCookie);
                }
    
                Page.PreLoad += master_Page_PreLoad;
            }
    
            protected void master_Page_PreLoad(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    // Set Anti-XSRF token
                    ViewState[AntiXsrfTokenKey] = Page.ViewStateUserKey;
                    ViewState[AntiXsrfUserNameKey] = Context.User.Identity.Name ?? String.Empty;
                }
                else
                {
                    // Validate the Anti-XSRF token
                    if ((string)ViewState[AntiXsrfTokenKey] != _antiXsrfTokenValue
                        || (string)ViewState[AntiXsrfUserNameKey] != (Context.User.Identity.Name ?? String.Empty))
                    {
                        throw new InvalidOperationException("Validation of Anti-XSRF token failed.");
                    }
                }
            }
    
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
    
            protected void Page_PreRender(object sender, EventArgs e)
            {
              using (ShoppingCartActions usersShoppingCart = new ShoppingCartActions())
              {
                string cartStr = string.Format("Cart ({0})", usersShoppingCart.GetCount());
                cartCount.InnerText = cartStr;
              }
            }
    
            public IQueryable<Category> GetCategories()
            {
              var _db = new WingtipToys.Models.ProductContext();
              IQueryable<Category> query = _db.Categories;
              return query;
            }
    
            protected void Unnamed_LoggingOut(object sender, LoginCancelEventArgs e)
            {
                Context.GetOwinContext().Authentication.SignOut();
            }
        }
    }
    

Zanim strona zostanie renderowana jako HTML, Page_PreRender zdarzenie zostanie podniesione. W procedurze Page_PreRender obsługi łączna liczba koszyka jest określana przez wywołanie GetCount metody . Zwrócona wartość jest dodawana do zakresu uwzględnionego w znaczniku cartCount strony Site.Master . Tagi <span> umożliwiają prawidłowe renderowanie elementów wewnętrznych. Gdy zostanie wyświetlona dowolna strona witryny, zostanie wyświetlona suma koszyka. Użytkownik może również kliknąć sumę koszyka, aby wyświetlić koszyk.

Testowanie ukończonego koszyka

Teraz możesz uruchomić aplikację, aby zobaczyć, jak można dodawać, usuwać i aktualizować elementy w koszyku. Łączna kwota koszyka będzie odzwierciedlać całkowity koszt wszystkich przedmiotów w koszyku.

  1. Naciśnij klawisz F5 , aby uruchomić aplikację.
    Zostanie otwarta przeglądarka i zostanie wyświetlona strona Default.aspx .

  2. Wybierz pozycję Samochody z menu nawigacji kategorii.

  3. Kliknij link Dodaj do koszyka obok pierwszego produktu.
    Strona ShoppingCart.aspx jest wyświetlana z sumą zamówienia.

  4. Wybierz pozycję Płaszczyzny z menu nawigacji kategorii.

  5. Kliknij link Dodaj do koszyka obok pierwszego produktu.

  6. Ustaw ilość pierwszego elementu w koszyku na wartość 3, a następnie zaznacz pole wyboru Usuń element drugiego elementu.

  7. Kliknij przycisk Aktualizuj , aby zaktualizować stronę koszyka i wyświetlić nową sumę zamówienia.

    Koszyk zakupów — aktualizacja koszyka

Podsumowanie

W tym samouczku utworzono koszyk dla przykładowej aplikacji Wingtip Toys Web Forms. W tym samouczku użyto funkcji Entity Framework Code First, adnotacji danych, silnie wpisanych kontrolek danych i powiązania modelu.

Koszyk zakupów obsługuje dodawanie, usuwanie i aktualizowanie elementów wybranych przez użytkownika do zakupu. Oprócz zaimplementowania funkcji koszyka do zakupów wiesz już, jak wyświetlać elementy koszyka w kontrolce GridView i obliczać sumę zamówienia.

Aby zrozumieć, jak działa opisana funkcja w prawdziwej aplikacji biznesowej, możesz wyświetlić przykład nopCommerce — ASP.NET oparty na open source koszyku zakupów handlu elektronicznego. Pierwotnie został zbudowany na Web Forms i przez lata przeniósł się do MVC, a teraz do ASP.NET Core.

Informacje o dodawaniu

ASP.NET Session State Overview