Sdílet prostřednictvím


Část 6: Členství v ASP.NET

Joe Stagner

Poznámka

Od napsání tohoto článku jsou zprostředkovatelé členství ASP.NET nahrazeni ASP.NET Identity. Důrazně doporučujeme aktualizovat aplikace tak, aby používaly platformu ASP.NET Identity Platform místo zprostředkovatelů členství, které byly uvedené v době psaní tohoto článku. ASP.NET Identity má oproti systému členství ASP.NET řadu výhod, mezi které patří:

  • Lepší výkon
  • Vylepšená rozšiřitelnost a testovatelnost
  • Podpora OAuth, OpenID Connect a dvojúrovňového ověřování
  • Podpora identit na základě deklarací identity
  • Lepší interoperabilita s ASP.Net Core

Tailspin Spyworks ukazuje, jak je mimořádně jednoduché vytvářet výkonné a škálovatelné aplikace pro platformu .NET. Ukazuje, jak používat skvělé nové funkce v ASP.NET 4 k vytvoření online obchodu, včetně nakupování, pokladny a správy.

Tato série kurzů podrobně popisuje všechny kroky k sestavení ukázkové aplikace Tailspin Spyworks. Část 6 přidává členství ASP.NET.

Práce s členstvím ASP.NET

Snímek obrazovky, který ukazuje, kde vybrat A S P dot NET Configuration

Klikněte na Zabezpečení.

Snímek obrazovky, který ukazuje, kde kliknout na Zabezpečení

Ujistěte se, že používáme ověřování pomocí formulářů.

Snímek obrazovky, který ukazuje, jak ověřit, že používáte ověřování pomocí formulářů

Pomocí odkazu Vytvořit uživatele vytvořte několik uživatelů.

Snímek obrazovky, který ukazuje, kde kliknout na Vytvořit uživatele

Až budete hotovi, podívejte se do okna Průzkumník řešení a aktualizujte zobrazení.

Snímek obrazovky, který ukazuje, kde se má zobrazení aktualizovat

Všimněte si, že ASPNETDB. Byla vytvořena pokuta MDF. Tento soubor obsahuje tabulky pro podporu základních ASP.NET služeb, jako je členství.

Teď můžeme začít s implementací procesu rezervace.

Začněte vytvořením stránky CheckOut.aspx.

Stránka CheckOut.aspx by měla být dostupná jenom přihlášeným uživatelům, takže omezíme přístup pro přihlášené uživatele a přesměrujeme uživatele, kteří nejsou přihlášení na stránku LogIn.

Za tímto účelem přidáme do části konfigurace našeho souboru web.config následující položky.

<location path="Checkout.aspx">
    <system.web>
      <authorization>
        <deny users="?" />
      </authorization>
    </system.web>
  </location>

Šablona pro ASP.NET Web Forms aplikací automaticky přidala oddíl ověřování do souboru web.config a vytvořila výchozí přihlašovací stránku.

<authentication mode="Forms">
      <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
    </authentication>

Soubor s kódem Login.aspx musíme upravit tak, aby migrovali anonymní nákupní košík, když se uživatel přihlásí. Následujícím způsobem změňte událost Page_Load.

using System.Web.Security;

protected void Page_Load(object sender, EventArgs e)
{
  // If the user is not submitting their credentials
  // save refferer
  if (!Page.IsPostBack)
     {
     if (Page.Request.UrlReferrer != null)
        {
        Session["LoginReferrer"] = Page.Request.UrlReferrer.ToString();
        }
      }
           
  // User is logged in so log them out.
  if (User.Identity.IsAuthenticated)
     {
     FormsAuthentication.SignOut();
     Response.Redirect("~/");
     }
}

Pak přidejte obslužnou rutinu události LoggedIn, jako je tato, která nastaví název relace na nově přihlášeného uživatele a změní dočasné ID relace v nákupním košíku na id uživatele voláním metody MigrateCart v naší třídě MyShoppingCart. (Implementováno v souboru .cs)

protected void LoginUser_LoggedIn(object sender, EventArgs e)
{
  MyShoppingCart usersShoppingCart = new MyShoppingCart();
  String cartId = usersShoppingCart.GetShoppingCartId();
  usersShoppingCart.MigrateCart(cartId, LoginUser.UserName);
            
  if(Session["LoginReferrer"] != null)
    {
    Response.Redirect(Session["LoginReferrer"].ToString());
    }

  Session["UserName"] = LoginUser.UserName;
}

Implementujte metodu MigrateCart() takto.

//--------------------------------------------------------------------------------------+
public void MigrateCart(String oldCartId, String UserName)
{
  using (CommerceEntities db = new CommerceEntities())
    {
    try
      {
      var myShoppingCart = from cart in db.ShoppingCarts
                           where cart.CartID == oldCartId
                           select cart;

      foreach (ShoppingCart item in myShoppingCart)
        {
        item.CartID = UserName;                 
        }
      db.SaveChanges();
      Session[CartId] = UserName;
      }
    catch (Exception exp)
      {
      throw new Exception("ERROR: Unable to Migrate Shopping Cart - " +     
                           exp.Message.ToString(), exp);
      }
    }           
}

V checkout.aspx použijeme EntityDataSource a GridView na stránce pokladny podobně jako na stránce nákupního košíku.

<div id="CheckOutHeader" runat="server" class="ContentHead">
  Review and Submit Your Order
</div>
<span id="Message" runat="server"><br />     
   <asp:Label ID="LabelCartHeader" runat="server" 
              Text="Please check all the information below to be sure it&#39;s correct.">
   </asp:Label>
</span><br /> 
<asp:GridView ID="MyList" runat="server" AutoGenerateColumns="False" 
              DataKeyNames="ProductID,UnitCost,Quantity" 
              DataSourceID="EDS_Cart" 
              CellPadding="4" GridLines="Vertical" CssClass="CartListItem" 
              onrowdatabound="MyList_RowDataBound" ShowFooter="True">
  <AlternatingRowStyle CssClass="CartListItemAlt" />
  <Columns>
    <asp:BoundField DataField="ProductID" HeaderText="Product ID" ReadOnly="True" 
                    SortExpression="ProductID"  />
    <asp:BoundField DataField="ModelNumber" HeaderText="Model Number" 
                    SortExpression="ModelNumber" />
    <asp:BoundField DataField="ModelName" HeaderText="Model Name" 
                    SortExpression="ModelName" />
    <asp:BoundField DataField="UnitCost" HeaderText="Unit Cost" ReadOnly="True" 
                    SortExpression="UnitCost" DataFormatString="{0:c}" />
    <asp:BoundField DataField="Quantity" HeaderText="Quantity" ReadOnly="True" 
                    SortExpression="Quantity" />
    <asp:TemplateField> 
      <HeaderTemplate>Item Total</HeaderTemplate>
      <ItemTemplate>
        <%# (Convert.ToDouble(Eval("Quantity")) * Convert.ToDouble(Eval("UnitCost")))%>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
  <FooterStyle CssClass="CartListFooter"/>
  <HeaderStyle  CssClass="CartListHead" />
</asp:GridView>   
    
<br />
<asp:imagebutton id="CheckoutBtn" runat="server" ImageURL="Styles/Images/submit.gif" 
                                  onclick="CheckoutBtn_Click">
</asp:imagebutton>
<asp:EntityDataSource ID="EDS_Cart" runat="server" 
                      ConnectionString="name=CommerceEntities" 
                      DefaultContainerName="CommerceEntities" 
                      EnableFlattening="False" 
                      EnableUpdate="True" 
                      EntitySetName="ViewCarts" 
                      AutoGenerateWhereClause="True" 
                      EntityTypeFilter="" 
                      Select="" Where="">
   <WhereParameters>
      <asp:SessionParameter Name="CartID" DefaultValue="0" 
                                          SessionField="TailSpinSpyWorks_CartID" />
   </WhereParameters>
</asp:EntityDataSource>

Všimněte si, že náš ovládací prvek GridView určuje "ondatabound" obslužnou rutinu události s názvem MyList_RowDataBound, takže pojďme tuto obslužnou rutinu události implementovat takto.

decimal _CartTotal = 0;

//--------------------------------------------------------------------------------------+
protected void MyList_RowDataBound(object sender, GridViewRowEventArgs e)
{
  if (e.Row.RowType == DataControlRowType.DataRow)
     {
     TailspinSpyworks.Data_Access.ViewCart myCart = new Data_Access.ViewCart();
     myCart = (TailspinSpyworks.Data_Access.ViewCart)e.Row.DataItem;
     _CartTotal += myCart.UnitCost * myCart.Quantity;
     }
   else if (e.Row.RowType == DataControlRowType.Footer)
     {
     if (_CartTotal > 0)
        {
        CheckOutHeader.InnerText = "Review and Submit Your Order";
        LabelCartHeader.Text = "Please check all the information below to be sure
                                                                it&#39;s correct.";
        CheckoutBtn.Visible = true;
        e.Row.Cells[5].Text = "Total: " + _CartTotal.ToString("C");
        }
     }
}

Tato metoda udržuje průběžný součet nákupního košíku, protože každý řádek je svázán a aktualizuje dolní řádek GridView.

V této fázi jsme implementovali "revizní" prezentaci objednávky, která má být zadána.

Pojďme zpracovat scénář prázdného košíku přidáním několika řádků kódu do události Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
   CheckOutHeader.InnerText = "Your Shopping Cart is Empty";
   LabelCartHeader.Text = "";
   CheckoutBtn.Visible = false;
}

Když uživatel klikne na tlačítko "Odeslat", spustíme následující kód v obslužné rutině události Odeslat kliknutí na tlačítko.

protected void CheckoutBtn_Click(object sender, ImageClickEventArgs e)
{
  MyShoppingCart usersShoppingCart = new MyShoppingCart();
  if (usersShoppingCart.SubmitOrder(User.Identity.Name) == true)
    {
    CheckOutHeader.InnerText = "Thank You - Your Order is Complete.";
    Message.Visible = false;
    CheckoutBtn.Visible = false;
    }
  else
    {
    CheckOutHeader.InnerText = "Order Submission Failed - Please try again. ";
    }
}

"maso" procesu odeslání objednávky musí být implementováno v metodě SubmitOrder() naší třídy MyShoppingCart.

SubmitOrder bude:

  • Vezměte všechny řádkové položky v nákupním košíku a použijte je k vytvoření nového záznamu objednávky a přidružených záznamů OrderDetails.
  • Vypočítejte datum expedice.
  • Vymažte nákupní košík.
//--------------------------------------------------------------------------------------+
public bool SubmitOrder(string UserName)
{
  using (CommerceEntities db = new CommerceEntities())
    {
    try
      {
      //------------------------------------------------------------------------+
      //  Add New Order Record                                                  |
      //------------------------------------------------------------------------+
      Order newOrder = new Order();
      newOrder.CustomerName = UserName;
      newOrder.OrderDate = DateTime.Now;
      newOrder.ShipDate = CalculateShipDate();
      db.Orders.AddObject(newOrder);
      db.SaveChanges();
         
      //------------------------------------------------------------------------+
      //  Create a new OderDetail Record for each item in the Shopping Cart     |
      //------------------------------------------------------------------------+
      String cartId = GetShoppingCartId();
      var myCart = (from c in db.ViewCarts where c.CartID == cartId select c);
      foreach (ViewCart item in myCart)
        {
        int i = 0;
        if (i < 1)
          {
          OrderDetail od = new OrderDetail();
          od.OrderID = newOrder.OrderID;
          od.ProductID = item.ProductID;
          od.Quantity = item.Quantity;
          od.UnitCost = item.UnitCost;
          db.OrderDetails.AddObject(od);
          i++;
          }

        var myItem = (from c in db.ShoppingCarts where c.CartID == item.CartID && 
                         c.ProductID == item.ProductID select c).FirstOrDefault();
        if (myItem != null)
          {
          db.DeleteObject(myItem);
          }
        }
      db.SaveChanges();                    
      }
    catch (Exception exp)
      {
      throw new Exception("ERROR: Unable to Submit Order - " + exp.Message.ToString(), 
                                                               exp);
      }
    } 
  return(true);
}

Pro účely této ukázkové aplikace vypočítáme datum expedice tak, že k aktuálnímu datu jednoduše přidáme dva dny.

//--------------------------------------------------------------------------------------+
DateTime CalculateShipDate()
{
   DateTime shipDate = DateTime.Now.AddDays(2);
   return (shipDate);
}

Spuštění aplikace nám umožní otestovat nákupní proces od začátku do konce.