Koszyk

Autor Erik Reitan

Pobierz program Wingtip zabawki (C#) lub Pobierz książkę elektroniczną (PDF)

Ta seria samouczków zawiera informacje na temat tworzenia aplikacji ASP.NET Web Forms przy użyciu ASP.NET 4,5 i Microsoft Visual Studio Express 2013 dla sieci Web. Projekt Visual Studio 2013 z C# kodem źródłowym jest dostępny do tej serii samouczków.

W tym samouczku opisano logikę biznesową wymaganą do dodania koszyka do przykładowej aplikacji Wingtip zabawki ASP.NET Web Forms. W tym samouczku przedstawiono poprzednie samouczki "Wyświetlanie elementów danych i szczegółów" oraz jest częścią serii samouczków dotyczących sklepu Wingtip. Po ukończeniu tego samouczka użytkownicy przykładowej aplikacji będą mogli dodawać, usuwać i modyfikować produkty w koszyku zakupów.

Zawartość:

  1. Jak utworzyć koszyk dla aplikacji sieci Web.
  2. Jak umożliwić użytkownikom dodawanie elementów do koszyka.
  3. Jak dodać kontrolkę GridView , aby wyświetlić szczegóły koszyka zakupów.
  4. Obliczanie i wyświetlanie sumy zamówienia.
  5. Jak usuwać i aktualizować elementy w koszyku zakupów.
  6. Jak uwzględnić licznik koszyka zakupów.

Funkcje kodu w tym samouczku:

  1. Entity Framework Code First
  2. Adnotacje danych
  3. Kontrolki danych o jednoznacznie określonym typie
  4. Powiązanie modelu

Tworzenie koszyka

Wcześniej w tej serii samouczków dodano strony i kod umożliwiający wyświetlenie danych produktu z bazy danych. W tym samouczku utworzysz koszyk do zarządzania produktami, które użytkownicy chcą kupić. Użytkownicy będą mogli przeglądać i dodawać elementy do koszyka, nawet jeśli nie są zarejestrowani lub zarejestrowani. Aby zarządzać dostępem do koszyka zakupów, użytkownicy są przypisani unikatowymi ID przy użyciu unikatowego identyfikatora globalnego (GUID), gdy użytkownik uzyskuje dostęp do koszyka po raz pierwszy. Ten ID będzie przechowywany przy użyciu stanu sesji ASP.NET.

Note

Stan sesji ASP.NET jest wygodnym miejscem do przechowywania informacji specyficznych dla użytkownika, które wygasną po opuszczeniu witryny przez użytkownika. W przypadku nieprawidłowego stanu sesji może to mieć wpływ na wydajność większych lokacji, jednak w celach demonstracyjnych dobrze jest korzystać ze stanu sesji. Przykładowy projekt Wingtip zabawki pokazuje, jak używać stanu sesji bez zewnętrznego dostawcy, w którym stan sesji jest przechowywany w procesie na serwerze sieci Web hostującym lokację. W przypadku większych lokacji, które udostępniają wiele wystąpień aplikacji lub dla lokacji, które uruchamiają wiele wystąpień aplikacji na różnych serwerach, należy rozważyć użycie usługi Windows Azure cache Service. Ta Cache Service zapewnia usługę rozproszonego buforowania, która jest zewnętrzna względem witryny sieci Web i rozwiązuje problem związany z używaniem stanu sesji w procesie. Aby uzyskać więcej informacji, zobacz jak używać stanu sesji ASP.NET z witrynami sieci Web systemu Windows Azure.

Dodaj CartItem jako klasę modelu

Wcześniej w tej serii samouczków został zdefiniowany schemat dla kategorii i danych produktu, tworząc klasy Category i Product w folderze modele . Teraz Dodaj nową klasę, aby zdefiniować schemat dla koszyka. W dalszej części tego samouczka dodasz klasę do obsługi dostępu do danych do tabeli CartItem. Ta klasa udostępnia logikę biznesową, która umożliwia dodawanie, usuwanie i aktualizowanie elementów w koszyku.

  1. Kliknij prawym przyciskiem myszy folder modele i wybierz polecenie Dodaj -> nowy element.

    Koszyk — 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ę Add (Dodaj).
    Nowy plik klasy zostanie wyświetlony w edytorze.

  5. Zastąp domyślny kod 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 definiujący każdy produkt dodawany przez użytkownika do koszyka zakupów. Ta klasa jest podobna do innych klas schematu utworzonych wcześniej w tej serii samouczków. Zgodnie z Konwencją Entity Framework Code First oczekuje, że klucz podstawowy dla tabeli CartItem będzie CartItemId lub ID. Jednak kod zastępuje zachowanie domyślne za pomocą atrybutu [Key] adnotacji danych. Atrybut Key właściwości ItemId określa, że właściwość ItemID jest kluczem podstawowym.

Właściwość CartId określa ID użytkownika, który jest skojarzony z elementem do zakupu. Dodasz kod w celu utworzenia tego użytkownika ID, gdy użytkownik uzyskuje dostęp do koszyka. Ten ID będzie również przechowywany jako zmienna sesji ASP.NET.

Aktualizowanie kontekstu produktu

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

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

  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 przestrzeń nazw System.Data.Entity, dzięki czemu masz dostęp do wszystkich podstawowych funkcji Entity Framework. Ta funkcja obejmuje możliwość wykonywania zapytań, wstawiania, aktualizowania i usuwania danych przez pracę z silnie określonymi obiektami. Klasa ProductContext dodaje dostęp do nowo dodanej klasy modelu CartItem.

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 tabeli CartItem. Klasa zawiera również logikę biznesową, która umożliwia dodawanie, usuwanie i aktualizowanie elementów w koszyku.

Logika koszyka zakupów, którą dodasz, będzie zawierać funkcje do zarządzania następującymi akcjami:

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

Strona koszyka zakupów (ShoppingCart. aspx) i koszyka zakupów zostaną użyte razem w celu uzyskania dostępu do danych koszyka zakupów. Na stronie koszyka zakupów zostaną wyświetlone wszystkie elementy dodawane przez użytkownika do koszyka zakupów. Poza stroną koszyka i klasą zakupów utworzysz stronę (AddToCart. aspx), aby dodać produkty do koszyka. Dodasz również kod do strony ProductList. aspx oraz strony ProductDetails. aspx , która będzie udostępniać link do strony AddToCart. aspx , dzięki czemu użytkownik może dodawać produkty do koszyka.

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

Koszyk — Dodawanie do koszyka zakupów

Gdy użytkownik kliknie link Dodaj do koszyka na stronie ProductList. aspx lub ProductDetails. aspx , aplikacja przejdzie do strony AddToCart. aspx , a następnie automatycznie do strony ShoppingCart. aspx . Na stronie AddToCart. aspx zostanie dodany wybór produktu do koszyka przez wywołanie metody w klasie ShoppingCart. Na stronie ShoppingCart. aspx zostaną wyświetlone produkty, które zostały dodane do koszyka.

Tworzenie klasy koszyka zakupów

Klasa ShoppingCart zostanie dodana do oddzielnego folderu w aplikacji, dzięki czemu będzie jasne rozróżnienie między modelem (folderem modeli), stronami (folderem głównym) i logiką (folderem logiki).

  1. W Eksplorator rozwiązańkliknij prawym przyciskiem myszy projekt WingtipToysi wybierz pozycję Dodaj->Nowy folder. Nadaj nazwę nowej logikifolderu.

  2. Kliknij prawym przyciskiem myszy folder logiki , a następnie wybierz pozycję Dodaj -> nowy element.

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

  4. Zastąp domyślny kod 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ędnienie poszczególnych produktów w koszyku na podstawie IDproduktu. Produkt zostanie dodany 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 koszyka służy do śledzenia elementów, które użytkownik ma w swoim koszyku. Jeśli użytkownik nie ma istniejącego koszyka ID, dla nich zostanie utworzony nowy koszyk ID. Jeśli użytkownik jest zalogowany jako zarejestrowanego użytkownika, ID koszyk zostanie ustawiony na nazwę użytkownika. Jeśli jednak użytkownik nie jest zalogowany, ID koszyka jest ustawiona na unikatową wartość (identyfikator GUID). Identyfikator GUID zapewnia, że dla każdego użytkownika jest tworzony tylko jeden koszyk, w oparciu o sesję.

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

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 klasie ShoppingCart, która została właśnie utworzona. Strona AddToCart. aspx będzie oczekiwać, że ID produktu zostanie do niego przeniesiona. Ten ID produktu będzie używany podczas wywoływania metody AddToCart w klasie ShoppingCart.

Note

Zmodyfikujesz kod w tle (AddToCart.aspx.cs) na tej stronie, a nie interfejs użytkownika strony (AddToCart. aspx).

Aby utworzyć funkcję dodawania do koszyka:

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

  2. Dodawanie standardowej nowej strony (formularz sieci Web) do aplikacji o nazwie AddToCart. aspx.

    Koszyk — Dodaj formularz sieci Web

  3. W Eksplorator rozwiązańkliknij prawym przyciskiem myszy stronę AddToCart. aspx , a następnie kliknij pozycję Wyświetl kod. Plik związany z kodem AddToCart.aspx.cs jest otwarty w edytorze.

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

    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 jest pobierany z ciągu zapytania. Następnie wystąpienie klasy koszyka zakupów jest tworzone i używane do wywołania metody AddToCart, która została dodana wcześniej w tym samouczku. Metoda AddToCart, zawarta w pliku ShoppingCartActions.cs , zawiera logikę umożliwiającą dodanie wybranego produktu do koszyka zakupów lub zwiększenie ilości produktu wybranego produktu. Jeśli produkt nie został dodany do koszyka zakupów, produkt zostanie dodany do tabeli CartItem 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 tabeli CartItem. Na koniec Strona przekierowuje z powrotem do strony ShoppingCart. aspx , którą dodasz w następnym kroku, gdzie użytkownik zobaczy zaktualizowaną listę elementów w koszyku.

Jak wspomniano wcześniej, ID użytkownika służy do identyfikowania produktów, które są skojarzone z określonym użytkownikiem. Ta ID jest dodawana do wiersza w tabeli CartItem za każdym razem, gdy użytkownik doda produkt do koszyka.

Tworzenie interfejsu użytkownika koszyka zakupów

Na stronie ShoppingCart. aspx zostaną wyświetlone produkty dodane przez użytkownika do koszyka zakupów. Umożliwia także dodawanie, usuwanie i aktualizowanie elementów w koszyku.

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

  2. Dodaj nową stronę (formularz sieci Web), która zawiera stronę wzorcową, wybierając formularz sieci Web 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 zakupów z bazy danych z formantem GridView . Po ustawieniu właściwości ItemType formantu GridView , wyrażenie powiązania danych Item jest dostępne w znaczniku kontrolki, a kontrolka zostanie silnie wpisana. Jak wspomniano wcześniej w tej serii samouczków, możesz wybrać szczegóły obiektu Item przy użyciu funkcji IntelliSense. Aby skonfigurować kontrolkę danych do używania powiązania modelu w celu wybrania danych, należy ustawić właściwość SelectMethod formantu. W powyższym znaczniku należy ustawić SelectMethod, aby użyć metody GetShoppingCartItems, która zwraca listę obiektów CartItem. Kontrolka danych GridView wywołuje metodę w odpowiednim czasie w cyklu życia strony i automatycznie wiąże zwrócone dane. Należy nadal dodać metodę GetShoppingCartItems.

Pobieranie elementów koszyka zakupów

Następnie Dodaj kod do kodu ShoppingCart.aspx.cs , 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 związany z kodem ShoppingCart.aspx.cs jest otwarty w edytorze.

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

    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, Kontrola danych GridView wywołuje metodę GetShoppingCartItems w odpowiednim czasie w cyklu życia strony i automatycznie wiąże zwrócone dane. Metoda GetShoppingCartItems tworzy wystąpienie obiektu ShoppingCartActions. Następnie kod używa tego wystąpienia do zwrócenia elementów w koszyku, wywołując metodę GetCartItems.

Dodawanie produktów do koszyka zakupów

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 ShoppingCart, która została dodana wcześniej w tym samouczku.

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

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

  2. Dodaj znaczniki wyróżnione kolorem żółtym do strony ProductList. aspx , aby cała strona była wyświetlana 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 dowiedzieć się, jak dodać produkty do koszyka.

  1. Naciśnij klawisz F5, aby uruchomić aplikację.
    Po utworzeniu bazy danych przez projekt zostanie otwarta przeglądarka i zostanie wyświetlona strona default. aspx .

  2. Wybierz pozycję samochody z menu nawigacji kategorii.
    Zostanie wyświetlona strona ProductList. aspx zawierająca tylko produkty należące do kategorii "samochody".

    Koszyk samochodów

  3. Kliknij link Dodaj do koszyka obok pierwszego produktu na liście (samochód wymienialny).
    Zostanie wyświetlona strona ShoppingCart. aspx pokazująca wybór w koszyku.

    Koszyk — koszyk

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

  5. Kliknij link Dodaj do koszyka obok pierwszego wymienionego produktu.
    Zostanie wyświetlona strona ShoppingCart. aspx z dodatkowym elementem.

  6. Zamknij okno przeglądarki.

Obliczanie i wyświetlanie sumy zamówienia

Oprócz dodawania produktów do koszyka zakupów należy dodać metodę GetTotal do klasy ShoppingCart i wyświetlić łączną kwotę zamówienia na stronie koszyka zakupów.

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

  2. Dodaj następującą metodę GetTotal wyróżnioną żółtym do klasy ShoppingCart, tak aby Klasa była wyświetlana w następujący sposób:

    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;
        }
      }
    }
    

Najpierw Metoda GetTotal Pobiera identyfikator koszyka dla użytkownika. Następnie Metoda pobiera kwotę koszyka przez pomnożenie ceny produktu przez ilość produktu dla każdego produktu wymienionego w koszyku.

Note

Powyższy kod używa typu dopuszczającego wartość null "int?". Typy dopuszczające wartości null mogą reprezentować wszystkie wartości typu podstawowego, a także jako wartość null. Aby uzyskać więcej informacji, zobacz używanie typów dopuszczających wartość null.

Modyfikowanie wyświetlania koszyka zakupów

Następnie zmodyfikujesz kod dla 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 polecenie Wyświetl kod.

  2. W pliku ShoppingCart.aspx.cs zaktualizuj procedurę obsługi Page_Load, dodając następujący kod w żół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();
        }
      }
    }
    

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

Testowanie całkowitego koszyka zakupów

Uruchom aplikację teraz, aby zobaczyć, jak nie tylko dodać produkt do koszyka, ale możesz zobaczyć łączną część koszyka zakupów.

  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.
    Zostanie wyświetlona strona ShoppingCart. aspx z sumą zamówień.

    Koszyk — suma dla koszyka

  4. Dodaj inne produkty (na przykład płaszczyznę) do koszyka.

  5. Na stronie ShoppingCart. aspx zostanie wyświetlona zaktualizowana suma dla wszystkich produktów, które zostały dodane.

    Koszyk — wiele produktów

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

Dodawanie przycisków aktualizacji i wyewidencjonowania do koszyka zakupów

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

  1. W Eksplorator rozwiązańOtwórz stronę ShoppingCart. aspx w folderze głównym projektu aplikacji sieci Web.

  2. Aby dodać przycisk Aktualizuj i przycisk wyewidencjonowania do strony ShoppingCart. aspx , Dodaj znacznik wyróżniony żół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 , zostanie wywołana procedura obsługi zdarzeń UpdateBtn_Click. Ta procedura obsługi zdarzeń wywoła kod, który zostanie dodany w następnym kroku.

Następnie można zaktualizować kod zawarty w pliku ShoppingCart.aspx.cs , aby przechodzić do pętli przez elementy koszyka i wywoływać metody RemoveItem i UpdateItem.

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

  2. Dodaj następujące sekcje kodu wyróżnione żółtymi 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) w celu dodania lub usunięcia elementów z koszyka. Gdy baza danych zostanie zaktualizowana w celu odzwierciedlenia aktualizacji koszyka, formant GridView zostanie zaktualizowany na stronie koszyka zakupów, wywołując metodę DataBind dla widoku GridView. Ponadto całkowita kwota zamówienia na stronie koszyka zakupów jest aktualizowana w celu odzwierciedlenia zaktualizowanej listy elementów.

Aktualizowanie i usuwanie elementów koszyka zakupów

Na stronie ShoppingCart. aspx można zobaczyć kontrolki, które zostały dodane do aktualizowania ilości elementu i usuwania elementu. Teraz Dodaj kod, który umożliwi działanie tych kontrolek.

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

  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łana z metody UpdateCartItems na stronie ShoppingCart.aspx.cs zawiera logikę do aktualizowania lub usuwania elementów z koszyka. Metoda UpdateShoppingCartDatabase wykonuje iterację wszystkich wierszy na liście koszyków zakupów. Jeśli element koszyka zakupów został oznaczony jako usunięty lub ilość jest mniejsza od 1, wywoływana jest metoda RemoveItem. W przeciwnym razie element koszyka zakupów jest sprawdzany pod kątem aktualizacji, gdy wywoływana jest metoda UpdateItem. Po usunięciu lub zaktualizowaniu elementu koszyka zostaną zapisane zmiany w bazie danych.

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

W następnym samouczku będziesz używać metody EmptyCart, aby wyczyścić koszyk po zakupie produktów. Jednak teraz użyjemy GetCount metody, która została właśnie dodana do pliku ShoppingCartActions.cs , aby określić, ile elementów znajduje się w koszyku zakupów.

Dodawanie licznika koszyka zakupów

Aby umożliwić użytkownikowi wyświetlanie łącznej liczby elementów w koszyku, należy dodać licznik do strony site. Master . Ten licznik również działa jako link do koszyka zakupów.

  1. W Eksplorator rozwiązańOtwórz stronę site. Master .

  2. Zmodyfikuj znacznik przez dodanie linku do koszyka zakupów, jak pokazano w sekcji żółtej, tak aby pojawił się w następujący sposób:

    <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 związany z plikiem 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();
            }
        }
    }
    

Przed renderowaniem strony jako HTML zostanie zgłoszone zdarzenie Page_PreRender. W obsłudze Page_PreRender, Łączna liczba koszyków zakupów jest określana przez wywołanie metody GetCount. Zwrócona wartość jest dodawana do zakresu cartCount zawartego w znaczniku strony . Tagi <span> umożliwiają prawidłowe renderowanie elementów wewnętrznych. Gdy zostanie wyświetlona dowolna strona witryny, zostanie wyświetlona suma koszyka zakupów. Użytkownik może również kliknąć opcję koszyka zakupów, aby wyświetlić koszyk.

Testowanie ukończonego koszyka zakupów

Teraz możesz uruchomić aplikację, aby zobaczyć, jak można dodawać, usuwać i aktualizować elementy w koszyku. Kwota koszyka zakupów będzie odzwierciedlać łączny koszt wszystkich elementó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.
    Zostanie wyświetlona strona ShoppingCart. aspx z sumą zamówień.

  4. Wybierz płaszczyzny z menu nawigacji kategorii.

  5. Kliknij link Dodaj do koszyka obok pierwszego produktu.

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

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

    Aktualizacja koszyka koszyka

Podsumowanie

W tym samouczku utworzono koszyk dla przykładowej aplikacji Wingtip zabawki Web Forms. W tym samouczku użyto Entity Framework Code First, adnotacji danych, kontrolek danych o jednoznacznie określonym typie i powiązania modelu.

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

Aby zrozumieć, jak opisana funkcja działa w prawdziwej aplikacji biznesowej, możesz zapoznać się z przykładem ASP.NET typu Open Source ( witryny systemu NopCommerce ). Pierwotnie został utworzony na formularzach sieci Web i w ciągu lat przenoszonych do MVC i teraz ASP.NET Core.

Dodatkowe informacje

ASP.NET Session State Overview