Freigeben über


Teil 6: ASP.NET Mitgliedschaft

von Joe Stagner

Hinweis

Da dieser Artikel geschrieben wurde, werden die ASP.NET Mitgliedschaftsanbieter von ASP.NET Identity abgelöst. Es wird dringend empfohlen, Apps so zu aktualisieren, dass sie die ASP.NET Identity Platform anstelle der Mitgliedschaftsanbieter verwenden, die zu dem Zeitpunkt dieses Artikels vorgestellt wurden. ASP.NET Identity hat eine Reihe von Vorteilen gegenüber dem ASP.NET Mitgliedschaftssystem, darunter:

  • Bessere Leistung
  • Verbesserte Erweiterbarkeit und Testbarkeit
  • Unterstützung für OAuth, OpenID Connect und zweistufige Authentifizierung
  • Anspruchsbasierte Identitätsunterstützung
  • Bessere Interoperabilität mit ASP.Net Core

Tailspin Spyworks zeigt, wie außerordentlich einfach es ist, leistungsstarke, skalierbare Anwendungen für die .NET-Plattform zu erstellen. Es zeigt, wie Sie die großartigen neuen Features in ASP.NET 4 verwenden, um einen Online-Shop zu erstellen, einschließlich Shopping, Checkout und Verwaltung.

In dieser Lernprogrammreihe werden alle Schritte zum Erstellen der Tailspin Spyworks-Beispielanwendung beschrieben. Teil 6 fügt ASP.NET Mitgliedschaft hinzu.

Arbeiten mit ASP.NET Mitgliedschaft

Screenshot, der zeigt, wo eine S P dot NET-Konfiguration ausgewählt werden soll.

Klicken Sie auf "Sicherheit".

Screenshot, der zeigt, wo auf

Stellen Sie sicher, dass wir die Formularauthentifizierung verwenden.

Screenshot, der zeigt, wie Sie bestätigen, dass Sie die Formularauthentifizierung verwenden.

Verwenden Sie den Link "Benutzer erstellen", um ein paar Benutzer zu erstellen.

Screenshot, der zeigt, wo auf

Wenn Sie fertig sind, öffnen Sie das Fenster "Projektmappen-Explorer" und aktualisieren Sie die Ansicht.

Screenshot, der zeigt, wo die Ansicht aktualisiert werden soll.

Beachten Sie, dass die Datei ASPNETDB.MDF erstellt wurde. Diese Datei enthält die Tabellen, die die wichtigsten ASP.NET Dienste wie Mitgliedschaft unterstützen.

Jetzt können wir mit der Implementierung des Checkout-Prozesses beginnen.

Erstellen Sie zunächst eine CheckOut.aspx Seite.

Die CheckOut.aspx-Seite sollte nur für Benutzer verfügbar sein, die angemeldet sind, daher werden wir den Zugriff auf angemeldete Benutzer beschränken und Benutzer, die nicht angemeldet sind, auf die LogIn-Seite umleiten.

Dazu fügen wir folgendes zum Konfigurationsabschnitt unserer web.config-Datei hinzu.

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

Die Vorlage für ASP.NET Web Forms-Anwendungen hat unserer web.config Datei automatisch einen Authentifizierungsbereich hinzugefügt und die Standardanmeldungsseite eingerichtet.

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

Wir müssen die Code-Behind-Datei von Login.aspx ändern, damit ein anonymer Einkaufswagen migriert wird, wenn sich der Benutzer anmeldet. Ändern Sie das Page_Load-Ereignis wie folgt.

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("~/");
     }
}

Fügen Sie dann einen "LoggedIn"-Ereignishandler hinzu, um den Sitzungsnamen auf den Benutzer festzulegen, der sich gerade angemeldet hat, und die temporäre Sitzungs-ID im Einkaufswagen auf die des Benutzers zu ändern, durch Aufruf der MigrateCart-Methode in unserer MyShoppingCart-Klasse. (In der datei .cs implementiert)

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

Implementieren Sie die MigrateCart()-Methode wie folgt.

//--------------------------------------------------------------------------------------+
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);
      }
    }           
}

In checkout.aspx verwenden wir eine EntityDataSource und ein GridView auf unserer Auscheckseite ähnlich wie auf unserer Einkaufswagenseite.

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

Beachten Sie, dass unser GridView-Steuerelement einen "ondatabound"-Ereignishandler namens MyList_RowDataBound angibt, damit wir diesen Ereignishandler wie folgt implementieren.

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

Diese Methode behält eine laufende Summe des Einkaufswagens bei, da jede Zeile gebunden ist und die untere Zeile der GridView aktualisiert.

In dieser Phase haben wir eine "Review"-Präsentation der Bestellung implementiert, die aufgegeben werden soll.

Behandeln wir ein leeres Einkaufswagenszenario, indem wir ein paar Codezeilen zu unserem Page_Load Ereignis hinzufügen:

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

Wenn der Benutzer auf die Schaltfläche "Absenden" klickt, führen wir den folgenden Code im Click-Ereignishandler der Absendenschaltfläche aus.

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

Das "Fleisch" des Bestellübermittlungsprozesses soll in der SubmitOrder()-Methode unserer MyShoppingCart-Klasse implementiert werden.

SubmitOrder wird Folgendes tun:

  • Nehmen Sie alle Positionen im Warenkorb, und verwenden Sie sie, um einen neuen Bestelldatensatz und die zugehörigen OrderDetails-Datensätze zu erstellen.
  • Berechnen des Versanddatums.
  • Löschen Sie den Einkaufswagen.
//--------------------------------------------------------------------------------------+
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);
}

Für die Zwecke dieser Beispielanwendung berechnen wir ein Lieferdatum, indem wir einfach zwei Tage zum aktuellen Datum hinzufügen.

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

Wenn Sie die Anwendung jetzt ausführen, können wir den Einkaufsvorgang von Anfang bis Ende testen.