Část 6: Členství v ASP.NET
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
Klikněte na Zabezpečení.
Ujistěte se, že používáme ověřování pomocí formulářů.
Pomocí odkazu Vytvořit uživatele vytvořte několik uživatelů.
Až budete hotovi, podívejte se do okna Průzkumník řešení a aktualizujte zobrazení.
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'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'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.