Freigeben über


Teil 6: ASP.NET-Mitgliedschaft

von Joe Stagner

Hinweis

Seit diesem Artikel wurden 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 zum Zeitpunkt der Veröffentlichung 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
  • Unterstützung für anspruchsbasierte Identitäten
  • Bessere Interoperabilität mit ASP.Net Core

Tailspin Spyworks zeigt, wie 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 Onlineshop zu erstellen, einschließlich Einkaufen, Auschecken und Verwaltung.

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

Arbeiten mit ASP.NET Mitgliedschaft

Screenshot: Auswahl von

Klicken Sie auf Sicherheit.

Screenshot, der zeigt, wo auf Sicherheit geklickt wird.

Stellen Sie sicher, dass die Formularauthentifizierung verwendet wird.

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

Verwenden Sie den Link "Benutzer erstellen", um einige Benutzer zu erstellen.

Screenshot: Klicken auf Benutzer erstellen

Wenn Sie fertig sind, lesen Sie das fenster Projektmappen-Explorer, und aktualisieren Sie die Ansicht.

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

Beachten Sie, dass aspnetdb. MDF fine wurde erstellt. Diese Datei enthält die Tabellen zur Unterstützung der kern-ASP.NET Dienste wie Mitgliedschaft.

Jetzt können wir mit der Implementierung des Auscheckvorgangs beginnen.

Erstellen Sie zunächst eine CheckOut.aspx-Seite.

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

Dazu fügen wir dem Konfigurationsabschnitt unserer web.config-Datei Folgendes 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 Abschnitt zur Authentifizierung hinzugefügt und die Standardanmeldungsseite eingerichtet.

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

Wir müssen die CodeBehind-Datei Login.aspx ändern, um einen anonymen Einkaufswagen zu migrieren, wenn sich der Benutzer anmeldet. Ändern Sie das ereignis Page_Load 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 wie diesen hinzu, um den Sitzungsnamen auf den neu angemeldeten Benutzer festzulegen und die temporäre Sitzungs-ID im Warenkorb in die des Benutzers zu ändern, indem Sie die MigrateCart-Methode in unserer MyShoppingCart-Klasse aufrufen. (Implementiert in der CS-Datei)

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 eine GridView auf unserer Auscheckseite ähnlich wie auf unserer Warenkorbseite.

<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 also implementieren wir diesen Ereignishandler wie folgt.

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

Mit dieser Methode wird eine laufende Summe des Warenkorbs beibehalten, während jede Zeile gebunden ist, und die untere Zeile des GridView-Steuerelements wird aktualisiert.

Zu diesem Zeitpunkt haben wir eine "Review"-Präsentation des zu aufgebenden Auftrags implementiert.

Wir behandeln ein Szenario mit einem leeren Warenkorb, indem wir dem Page_Load-Ereignis einige Codezeilen 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 Ereignishandler "Submit Button Click" 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 "Meat" des Bestellübermittlungsprozesses muss in der SubmitOrder()-Methode unserer MyShoppingCart-Klasse implementiert werden.

SubmitOrder führt Folgendes aus:

  • Nehmen Sie alle Positionen in den Warenkorb, und verwenden Sie sie, um einen neuen Bestelldatensatz und die zugehörigen OrderDetails-Datensätze zu erstellen.
  • Berechnen Sie das Versanddatum.
  • Löschen Sie den Warenkorb.
//--------------------------------------------------------------------------------------+
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 Versanddatum, 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.