Bölüm 7: Özellik Ekleme

tarafından Joe Stagner

Tailspin Spyworks, .NET platformu için güçlü, ölçeklenebilir uygulamalar oluşturmanın ne kadar basit olduğunu gösterir. Alışveriş, ödeme ve yönetim gibi çevrimiçi bir mağaza oluşturmak için ASP.NET 4'teki harika yeni özelliklerin nasıl kullanılacağını gösterir.

Bu öğretici serisi, Tailspin Spyworks örnek uygulamasını derlemek için atılan tüm adımların ayrıntılarını içerir. 7. Bölüm hesap incelemesi, ürün incelemeleri ve "popüler öğeler" ve "ayrıca satın alınan" kullanıcı denetimleri gibi ek özellikler ekler.

Özellik Ekleme

Kullanıcılar kataloğumuza göz atabiliyor, alışveriş sepetlerine ürün yerleştirebiliyor ve kullanıma alma işlemini tamamlayabiliyor olsa da, sitemizi geliştirmek için ekleyebileceğimiz bir dizi destekleyici özellik vardır.

  1. Hesap Gözden Geçirme (Verilen siparişleri listeleyin ve ayrıntıları görüntüleyin.)
  2. Ön sayfaya bağlama özgü bazı içerikler ekleyin.
  3. Kullanıcıların katalogdaki ürünleri gözden geçirmesini sağlamak için bir özellik ekleyin.
  4. Popüler Öğeler'i görüntülemek ve denetimi ön sayfada yerleştirmek için bir Kullanıcı Denetimi oluşturun.
  5. "Ayrıca Satın Alınan" bir kullanıcı denetimi oluşturun ve bunu ürün ayrıntıları sayfasına ekleyin.
  6. Kişi Sayfası ekleyin.
  7. Hakkında Sayfası ekleyin.
  8. Genel Hata

Hesabı Gözden Geçirme

"Hesap" klasöründe biri OrderList.aspx, diğeri de OrderDetails.aspx adlı iki .aspx sayfası oluşturun

OrderList.aspx, daha önce yaptığımız gibi GridView ve EntityDataSource denetimlerini de kullanacaktır.

<div class="ContentHead">Order History</div><br />

<asp:GridView ID="GridView_OrderList" runat="server" AllowPaging="True" 
              ForeColor="#333333" GridLines="None" CellPadding="4" Width="100%" 
              AutoGenerateColumns="False" DataKeyNames="OrderID" 
              DataSourceID="EDS_Orders" AllowSorting="True" ViewStateMode="Disabled" >
  <AlternatingRowStyle BackColor="White" />
  <Columns>
    <asp:BoundField DataField="OrderID" HeaderText="OrderID" ReadOnly="True" 
                    SortExpression="OrderID" />
    <asp:BoundField DataField="CustomerName" HeaderText="Customer" 
                    SortExpression="CustomerName" />
    <asp:BoundField DataField="OrderDate" HeaderText="Order Date" 
                    SortExpression="OrderDate" />
    <asp:BoundField DataField="ShipDate" HeaderText="Ship Date" 
                    SortExpression="ShipDate" />
    <asp:HyperLinkField HeaderText="Show Details" Text="Show Details" 
                 DataNavigateUrlFields="OrderID" 
                 DataNavigateUrlFormatString="~/Account/OrderDetails.aspx?OrderID={0}" />
  </Columns>
  <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
  <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
  <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
  <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
  <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
  <SortedAscendingCellStyle BackColor="#FDF5AC" />
  <SortedAscendingHeaderStyle BackColor="#4D0000" />
  <SortedDescendingCellStyle BackColor="#FCF6C0" />
  <SortedDescendingHeaderStyle BackColor="#820000" />
  <SortedAscendingCellStyle BackColor="#FDF5AC"></SortedAscendingCellStyle>
  <SortedAscendingHeaderStyle BackColor="#4D0000"></SortedAscendingHeaderStyle>
  <SortedDescendingCellStyle BackColor="#FCF6C0"></SortedDescendingCellStyle>
  <SortedDescendingHeaderStyle BackColor="#820000"></SortedDescendingHeaderStyle>
</asp:GridView>

<asp:EntityDataSource ID="EDS_Orders" runat="server" EnableFlattening="False" 
                      AutoGenerateWhereClause="True" 
                      Where="" 
                      OrderBy="it.OrderDate DESC"
                      ConnectionString="name=CommerceEntities"  
                      DefaultContainerName="CommerceEntities" 
                      EntitySetName="Orders" >
   <WhereParameters>
      <asp:SessionParameter Name="CustomerName" SessionField="UserName" />
   </WhereParameters>
</asp:EntityDataSource>

EntityDataSource, kullanıcı günlüğü açıkken bir oturum değişkeninde ayarladığımız UserName (Bkz. WhereParameter) filtrelenmiş Siparişler tablosundan kayıtları seçer.

Ayrıca GridView'un HyperlinkField içindeki şu parametrelere de dikkat edin:

DataNavigateUrlFields="OrderID" DataNavigateUrlFormatString="~/Account/OrderDetails.aspx?OrderID={0}"

Bunlar, OrderDetails.aspx sayfasına QueryString parametresi olarak OrderID alanını belirten her ürün için Sipariş ayrıntıları görünümünün bağlantısını belirtir.

OrderDetails.aspx

Siparişler'e erişmek için EntityDataSource denetimi, Sipariş verilerini görüntülemek için bir FormView ve Order'ın satır öğelerini görüntülemek için GridView ile başka bir EntityDataSource kullanacağız.

<asp:FormView ID="FormView1" runat="server" CellPadding="4" 
                             DataKeyNames="OrderID" 
                             DataSourceID="EDS_Order" ForeColor="#333333" Width="250px">
   <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
   <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
   <ItemTemplate>
      OrderID : <%# Eval("OrderID") %><br />
      CustomerName : <%# Eval("CustomerName") %><br />
      Order Date : <%# Eval("OrderDate") %><br />
      Ship Date : <%# Eval("ShipDate") %><br />
   </ItemTemplate>
   <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
   <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
</asp:FormView>
<asp:EntityDataSource ID="EDS_Order" runat="server"  EnableFlattening="False" 
                      ConnectionString="name=CommerceEntities" 
                      DefaultContainerName="CommerceEntities" 
                      EntitySetName="Orders" 
                      AutoGenerateWhereClause="True" 
                      Where="" 
                      EntityTypeFilter="" Select="">
   <WhereParameters>
      <asp:QueryStringParameter Name="OrderID" QueryStringField="OrderID" Type="Int32" />
   </WhereParameters>
</asp:EntityDataSource>

<asp:GridView ID="GridView_OrderDetails" runat="server" 
              AutoGenerateColumns="False" 
              DataKeyNames="ProductID,UnitCost,Quantity" 
              DataSourceID="EDS_OrderDetails" 
              CellPadding="4" GridLines="Vertical" CssClass="CartListItem" 
              onrowdatabound="MyList_RowDataBound" ShowFooter="True" 
              ViewStateMode="Disabled">
   <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> 
 <asp:EntityDataSource ID="EDS_OrderDetails" runat="server" 
                       ConnectionString="name=CommerceEntities" 
                       DefaultContainerName="CommerceEntities" 
                       EnableFlattening="False" 
                       EntitySetName="VewOrderDetails" 
                       AutoGenerateWhereClause="True" 
                       Where="">
   <WhereParameters>
     <asp:QueryStringParameter Name="OrderID" QueryStringField="OrderID" Type="Int32" />
   </WhereParameters>
</asp:EntityDataSource>

ArkaDaki Kod dosyasında (OrderDetails.aspx.cs) iki küçük temizlik parçasımız vardır.

Öncelikle OrderDetails'in her zaman bir OrderId aldığından emin olmamız gerekir.

protected void Page_Load(object sender, EventArgs e)
{
  if (String.IsNullOrEmpty(Request.QueryString["OrderId"]))
     {
     Response.Redirect("~/Account/OrderList.aspx");
     }
}

Ayrıca, satır öğelerindeki sipariş toplamını hesaplamamız ve görüntülememiz gerekir.

decimal _CartTotal = 0;

protected void MyList_RowDataBound(object sender, GridViewRowEventArgs e)
{
  if (e.Row.RowType == DataControlRowType.DataRow)
     {
     TailspinSpyworks.Data_Access.VewOrderDetail myCart = new 
                                                        Data_Access.VewOrderDetail();
     myCart = (TailspinSpyworks.Data_Access.VewOrderDetail)e.Row.DataItem;
     _CartTotal += Convert.ToDecimal(myCart.UnitCost * myCart.Quantity);
     }
   else if (e.Row.RowType == DataControlRowType.Footer)
     {
     e.Row.Cells[5].Text = "Total: " + _CartTotal.ToString("C");
   }
}

Giriş Sayfası

Default.aspx sayfasına biraz statik içerik ekleyelim.

İlk olarak bir "İçerik" klasörü ve bunun içinde bir Resimler klasörü oluşturacağım (ve giriş sayfasında kullanılacak bir resim ekliyorum.)

Default.aspx sayfasının alt yer tutucusuna aşağıdaki işaretlemeyi ekleyin.

<h2>
  <asp:LoginView ID="LoginView_VisitorGreeting" runat="server">
    <AnonymousTemplate>
       Welcome to the Store !
    </AnonymousTemplate>
    <LoggedInTemplate>
      Hi <asp:LoginName ID="LoginName_Welcome" runat="server" />. Thanks for coming back. 
    </LoggedInTemplate>
  </asp:LoginView>
</h2>

<p><strong>TailSpin Spyworks</strong> demonstrates how extraordinarily simple it is to create powerful, scalable applications for the .NET platform. </p>
<table>
  <tr>
    <td>               
      <h3>Some Implementation Features.</h3>
      <ul>
                <li><a href="#">CSS Based Design.</a></li>
                <li><a href="#">Data Access via Linq to Entities.</a></li>
                <li><a href="#">MasterPage driven design.</a></li>
                <li><a href="#">Modern ASP.NET Controls User.</a></li>
                <li><a href="#">Integrated Ajac Control Toolkit Editor.</a></li>
        </ul>
    </td>
    <td>
        <img src="Content/Images/SampleProductImage.gif" alt=""/>
    </td>
  </tr>
</table>
    
<table>
  <tr>
    <td colspan="2"><hr /></td>
  </tr>
  <tr>
    <td>               
        <!-- Popular Items -->
    </td>
    <td>  
      <center><h3>Ecommerce the .NET 4 Way</h3></center>
      <blockquote>
        <p>
        ASP.NET offers web developers the benefit of more that a decade of innovation. 
        This   demo leverages many of the latest features of ASP.NET development to     
        illustrate really simply building rich web applications with ASP.NET can be. 
        For more information about build web applications with ASP.NET please visit the 
        community web site at www.asp.net
        </p>
      </blockquote>
    </td>
  </tr>
</table>

<h3>Spyworks Event Calendar</h3>
<table>
  <tr class="rowH">
    <th>Date</th>
    <th>Title</th>
    <th>Description</th>
  </tr>
  <tr class="rowA">
    <td>June 01, 2011</td>
    <td>Sed vestibulum blandit</td>
    <td>
    Come and check out demos of all the newest Tailspin Spyworks products and experience 
    them hands on.
    </td>
  </tr>
  <tr class="rowB">
    <td>November 28, 2011</td>
    <td>Spyworks Product Demo</td>
    <td>
    Come and check out demos of all the newest Tailspin Spyworks products and experience 
    them hands on.
    </td>
  </tr>
  <tr class="rowA">
    <td>November 23, 2011</td>
    <td>Spyworks Product Demo</td>
    <td>
     Come and check out demos of all the newest Tailspin Spyworks products and experience 
     them hands on.
    </td>
  </tr>
  <tr class="rowB">
    <td>November 21, 2011</td>
    <td>Spyworks Product Demo</td>
    <td>
    Come and check out demos of all the newest Tailspin Spyworks products and experience 
    them hands on.
    </td>
  </tr>
</table>

Ürün İncelemeleri

İlk olarak, ürün incelemesi girmek için kullanabileceğimiz bir formun bağlantısını içeren bir düğme ekleyeceğiz.

<div class="SubContentHead">Reviews</div><br />
<a id="ReviewList_AddReview" href="ReviewAdd.aspx?productID=<%# Eval("ProductID") %>">
   <img id="Img2" runat="server" 
        src="~/Styles/Images/review_this_product.gif" alt="" />
</a>

Bağlantı konumunu gösteren ekran görüntüsü.

Sorgu dizesinde ProductID değerini geçirdiğimize dikkat edin

Şimdi ReviewAdd.aspx adlı bir sayfa ekleyelim

Bu sayfada ASP.NET AJAX Denetim Araç Seti kullanılır. Henüz yapmadıysanız, DevExpress'ten indirebilirsiniz ve araç setini Visual Studio ile kullanılacak şekilde ayarlama yönergeleri burada verilmiştir https://www.asp.net/learn/ajax-videos/video-76.aspx.

Tasarım modunda, denetimleri ve doğrulayıcıları araç kutusundan sürükleyin ve aşağıdakine benzer bir form oluşturun.

Formu gösteren ekran görüntüsü.

İşaretler şuna benzer olacaktır.

<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</asp:ToolkitScriptManager>
<div class="ContentHead">Add Review - <asp:label id="ModelName" runat="server" /></div>
<div>
  <span class="NormalBold">Name</span><br />
  <asp:TextBox id="Name" runat="server" Width="400px" /><br />
  <asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator1" 
                              ControlToValidate="Name" 
                              Display="Dynamic" 
                              CssClass="ValidationError" 
                              ErrorMessage="'Name' must not be left blank."  /><br />
  <span class="NormalBold">Email</span><br />
  <asp:TextBox id="Email" runat="server" Width="400px" /><br />
  <asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator2" 
                              ControlToValidate="Email" Display="Dynamic" 
                              CssClass="ValidationError" 
                              ErrorMessage="'Email' must not be left blank." />
  <br /><hr /><br />
  <span class="NormalBold">Rating</span><br /><br />
  <asp:RadioButtonList ID="Rating" runat="server">
    <asp:ListItem value="5" selected="True" 
             Text='<img src="Styles/Images/reviewrating5.gif" alt=""> (Five Stars) '  />
    <asp:ListItem value="4" selected="True" 
             Text='<img src="Styles/Images/reviewrating4.gif" alt=""> (Four Stars) '  />
    <asp:ListItem value="3" selected="True" 
             Text='<img src="Styles/Images/reviewrating3.gif" alt=""> (Three Stars) '  />
    <asp:ListItem value="2" selected="True" 
             Text='<img src="Styles/Images/reviewrating2.gif" alt=""> (Two Stars) '  />
    <asp:ListItem value="1" selected="True" 
             Text='<img src="Styles/Images/reviewrating1.gif" alt=""> (One Stars) '  />
  </asp:RadioButtonList>
  <br /><hr /><br />
  <span class="NormalBold">Comments</span><br />
  <cc1:Editor ID="UserComment" runat="server" />
  <asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator3" 
                              ControlToValidate="UserComment" Display="Dynamic" 
                              CssClass="ValidationError" 
                              ErrorMessage="Please enter your comment." /><br /><br />
  <asp:ImageButton ImageURL="Styles/Images/submit.gif" runat="server" 
                   id="ReviewAddBtn" onclick="ReviewAddBtn_Click" />
  <br /><br /><br />
</div>

İncelemeleri girebileceğimize göre, bu incelemeleri ürün sayfasında görüntüleyeceğiz.

Bu işaretlemeyi ProductDetails.aspx sayfasına ekleyin.

<asp:ListView ID="ListView_Comments" runat="server" 
              DataKeyNames="ReviewID,ProductID,Rating" DataSourceID="EDS_CommentsList">
  <ItemTemplate>
    <tr>
      <td><%# Eval("CustomerName") %></td>
      <td>
        <img src='Styles/Images/ReviewRating_d<%# Eval("Rating") %>.gif' alt="">
        <br />
      </td>
      <td>
        <%# Eval("Comments") %>
      </td>
    </tr>
  </ItemTemplate>
  <AlternatingItemTemplate>
    <tr>
      <td><%# Eval("CustomerName") %></td>
      <td>
        <img src='Styles/Images/ReviewRating_da<%# Eval("Rating") %>.gif' alt="">
        <br />
      </td>
      <td><%# Eval("Comments") %></td>
    </tr>
  </AlternatingItemTemplate>
   <EmptyDataTemplate>
     <table runat="server">
       <tr><td>There are no reviews yet for this product.</td></tr>
     </table>
  </EmptyDataTemplate>
  <LayoutTemplate>
    <table runat="server">
      <tr runat="server">
        <td runat="server">
          <table ID="itemPlaceholderContainer" runat="server" border="1">
            <tr runat="server">
              <th runat="server">Customer</th>
              <th runat="server">Rating</th>
              <th runat="server">Comments</th>
             </tr>
             <tr ID="itemPlaceholder" runat="server"></tr>
           </table>
         </td>
       </tr>
       <tr runat="server">
         <td runat="server">
           <asp:DataPager ID="DataPager1" runat="server">
             <Fields>
               <asp:NextPreviousPagerField ButtonType="Button" 
                                           ShowFirstPageButton="True"
                                           ShowLastPageButton="True" />
             </Fields>
           </asp:DataPager>
         </td>
       </tr>
     </table>
  </LayoutTemplate>
</asp:ListView>
<asp:EntityDataSource ID="EDS_CommentsList" runat="server"  EnableFlattening="False" 
                       AutoGenerateWhereClause="True" 
                       EntityTypeFilter="" 
                       Select="" Where=""
                       ConnectionString="name=CommerceEntities" 
                       DefaultContainerName="CommerceEntities" 
                       EntitySetName="Reviews">
   <WhereParameters>
    <asp:QueryStringParameter Name="ProductID" QueryStringField="productID"  
                                               Type="Int32" />
  </WhereParameters>
</asp:EntityDataSource>

Uygulamamızı şimdi çalıştırmak ve bir ürüne gitmek, müşteri incelemeleri de dahil olmak üzere ürün bilgilerini gösterir.

Müşteri incelemelerini gösteren ekran görüntüsü.

Popüler Öğeler Denetimi (Kullanıcı Denetimleri Oluşturma)

Web sitenizde satışları artırmak için popüler veya ilgili ürünleri "önerik satış" için birkaç özellik ekleyeceğiz.

Bu özelliklerden ilki, ürün kataloğumuzdaki daha popüler ürünün bir listesi olacaktır.

Uygulamamızın giriş sayfasında en çok satan öğeleri görüntülemek için bir "Kullanıcı Denetimi" oluşturacağız. Bu bir denetim olacağından, denetimi Visual Studio'nun tasarımcısında sürükleyip istediğimiz sayfaya bırakarak herhangi bir sayfada kullanabiliriz.

Visual Studio'nun çözüm gezgininde çözüm adına sağ tıklayın ve "Denetimler" adlı yeni bir dizin oluşturun. Bunu yapmak gerekli olmasa da, "Denetimler" dizininde tüm kullanıcı denetimlerimizi oluşturarak projemizin düzenli kalmasına yardımcı olacağız.

Denetimler klasörüne sağ tıklayın ve "Yeni Öğe" öğesini seçin:

Yeni Öğe'nin seçileceği yeri gösteren ekran görüntüsü.

"PopularItems" denetimimiz için bir ad belirtin. Kullanıcı denetimleri için dosya uzantısının .aspx değil .ascx olduğuna dikkat edin.

Popüler Öğeler Kullanıcı denetimimiz aşağıdaki gibi tanımlanacaktır.

<%@ OutputCache Duration="3600" VaryByParam="None" %>
<div class="MostPopularHead">Our most popular items this week</div>
<div id="PanelPopularItems" runat="server">
  <asp:Repeater ID="RepeaterItemsList" runat="server">
    <HeaderTemplate></HeaderTemplate>
      <ItemTemplate>               
        <a class='MostPopularItemText' 
           href='ProductDetails.aspx?productID=<%# Eval("ProductId") %>'>
                                               <%# Eval("ModelName") %></a><br />              
      </ItemTemplate>
    <FooterTemplate></FooterTemplate>
  </asp:Repeater>
</div>

Burada bu uygulamada henüz kullanmadığımız bir yöntem kullanıyoruz. Repeater denetimini kullanıyoruz ve veri kaynağı denetimi kullanmak yerine Repeater Denetimini bir LINQ to Entities sorgunun sonuçlarına bağlıyoruz.

Denetimimizin arkasındaki kodda bunu aşağıdaki gibi yaparız.

using TailspinSpyworks.Data_Access;

protected void Page_Load(object sender, EventArgs e)
{
  using (CommerceEntities db = new CommerceEntities())
    {
    try
      {
      var query = (from ProductOrders in db.OrderDetails
                        join SelectedProducts in db.Products on ProductOrders.ProductID  
                        equals SelectedProducts.ProductID
                        group ProductOrders by new
                            {
                            ProductId = SelectedProducts.ProductID,
                            ModelName = SelectedProducts.ModelName
                            } into grp
                        select new
                            {
                            ModelName = grp.Key.ModelName,
                            ProductId = grp.Key.ProductId,
                            Quantity = grp.Sum(o => o.Quantity)
                            } into orderdgrp where orderdgrp.Quantity > 0 
                        orderby orderdgrp.Quantity descending select orderdgrp).Take(5);

                    RepeaterItemsList.DataSource = query;
                    RepeaterItemsList.DataBind(); 
      }
    catch (Exception exp)
      {
      throw new Exception("ERROR: Unable to Load Popular Items - " + 
                           exp.Message.ToString(), exp);
      }
    }
}

Ayrıca, denetimimizin işaretlemesinin en üstündeki bu önemli satırı da unutmayın.

<%@ OutputCache Duration="3600" VaryByParam="None" %>

En popüler öğeler dakika bazında değişmeyeceğinden, uygulamamızın performansını artırmak için bir canlanma yönergesi ekleyebiliriz. Bu yönerge, denetim kodunun yalnızca denetimin önbelleğe alınmış çıkışının süresi dolduğunda yürütülmesine neden olur. Aksi takdirde, denetimin çıktısının önbelleğe alınmış sürümü kullanılır.

Şimdi tek yapmamız gereken Default.aspx sayfamıza yeni denetimimizi eklemektir.

Denetimin bir örneğini Varsayılan formumuzun açık sütununa yerleştirmek için sürükleyip bırakma özelliğini kullanın.

Denetimin bir örneğinin nereye yerleştirildiğini gösteren ekran görüntüsü.

Artık uygulamamızı çalıştırdığımızda giriş sayfası en popüler öğeleri görüntüler.

Giriş sayfasının en popüler öğeleri nasıl görüntülediğini gösteren ekran görüntüsü.

"Ayrıca Satın Alınan" Denetim (Parametrelerle Kullanıcı Denetimleri)

Oluşturacağımız ikinci Kullanıcı Denetimi, bağlam özgüllüğü ekleyerek önerili satışı bir sonraki düzeye taşır.

İlk "Ayrıca Satın Alınan" öğeleri hesaplama mantığı önemsiz değildir.

"Ayrıca Satın Alınan" denetimimiz, seçili durumdaki ProductID için OrderDetails kayıtlarını (daha önce satın alınmış) seçer ve bulunan her benzersiz sipariş için OrderID'leri alır.

Ardından tüm bu Siparişlerden al ürünlerini seçip satın alınan miktarları toplayacağız. Ürünleri bu miktar toplamına göre sıralayacağız ve ilk beş öğeyi görüntüleyeceğiz.

Bu mantığın karmaşıklığı göz önüne alındığında, bu algoritmayı saklı yordam olarak uygulayacağız.

Saklı yordam için T-SQL aşağıdaki gibidir.

ALTER PROCEDURE dbo.SelectPurchasedWithProducts
 @ProductID int
AS
        SELECT  TOP 5 
    OrderDetails.ProductID,
    Products.ModelName,
    SUM(OrderDetails.Quantity) as TotalNum

FROM    
    OrderDetails
  INNER JOIN Products ON OrderDetails.ProductID = Products.ProductID

WHERE   OrderID IN 
(
    /* This inner query should retrieve all orders that have contained the productID */
    SELECT DISTINCT OrderID 
    FROM OrderDetails
    WHERE ProductID = @ProductID
)
AND OrderDetails.ProductID != @ProductID 

GROUP BY OrderDetails.ProductID, Products.ModelName 

ORDER BY TotalNum DESC
RETURN

Bu saklı yordamın (SelectPurchasedWithProducts) uygulamamıza dahil ettiğimizde veritabanında mevcut olduğunu ve Varlık Veri Modeli'ni oluşturduğumuzda, ihtiyacımız olan Tablo ve Görünümlere ek olarak Varlık Veri Modeli'nin bu saklı yordamı içermesi gerektiğini belirttik.

Varlık Veri Modeli'nden saklı yordama erişmek için işlevi içeri aktarmamız gerekir.

Çözüm Gezgini'nde Varlık Veri Modeli'ne çift tıklayarak tasarımcıda açın ve Model Tarayıcısı'nı açın, ardından tasarımcıya sağ tıklayıp "İşlev İçeri Aktarma Ekle"yi seçin.

İşlev İçeri Aktarma Ekle'nin seçileceği yeri gösteren ekran görüntüsü.

Bunu yaptığınızda bu iletişim kutusu açılır.

Aç iletişim kutusunu gösteren ekran görüntüsü.

Yukarıda gördüğünüz gibi alanları doldurun, "SelectPurchasedWithProducts" öğesini seçin ve içeri aktarılan işlevimizin adı için yordam adını kullanın.

"Tamam"a tıklayın.

Bunu yaptıktan sonra, modeldeki başka herhangi bir öğe olabileceğimiz için saklı yordama göre programlayabiliriz.

Bu nedenle, "Denetimler" klasörünüzde AlsoPurchased.ascx adlı yeni bir kullanıcı denetimi oluşturun.

Bu denetimin işaretlemesi PopularItems denetimine çok tanıdık gelecek.

<div>
<div class="MostPopularHead">
<asp:Label ID="LabelTitle" runat="server" Text=" Customers who bought this also bought:"></asp:Label></div>
<div id="PanelAlsoBoughtItems" runat="server">
    <asp:Repeater ID="RepeaterItemsList" runat="server">
       <HeaderTemplate></HeaderTemplate>
          <ItemTemplate>               
             <a class='MostPopularItemText' href='ProductDetails.aspx?productID=<%# Eval("ProductId") %>'><%# Eval("ModelName") %></a><br />              
          </ItemTemplate>
       <FooterTemplate></FooterTemplate>
    </asp:Repeater>
</div>
</div>

Önemli fark, işlenecek öğe ürüne göre farklılık göstereceğinden çıkışı önbelleğe almamadır.

ProductId denetimi için bir "özellik" olacaktır.

private int _ProductId;

public int ProductId
{
get { return _ProductId ; }
set { _ProductId = Convert.ToInt32(value); }
}

Denetimin PreRender olay işleyicisinde üç şey yapmamız gerekir.

  1. ProductID değerinin ayarlandığından emin olun.
  2. Geçerli ürünle birlikte satın alınmış ürünler olup olmadığına bakın.
  3. #2'de belirlenen bazı öğelerin çıkışını yapın.

Saklı yordamı model aracılığıyla çağırmanın ne kadar kolay olduğunu unutmayın.

//--------------------------------------------------------------------------------------+
protected void Page_PreRender(object sender, EventArgs e)
{
  if (_ProductId < 1)
     {
     // This should never happen but we could expand the use of this control by reducing 
     // the dependency on the query string by selecting a few RANDOME products here. 
     Debug.Fail("ERROR : The Also Purchased Control Can not be used without 
                         setting the ProductId.");
     throw new Exception("ERROR : It is illegal to load the AlsoPurchased COntrol 
                                  without setting a ProductId.");
     }
      
  int ProductCount = 0;
  using (CommerceEntities db = new CommerceEntities())
    {
    try
      {
      var v = db.SelectPurchasedWithProducts(_ProductId);
      ProductCount = v.Count();
      }
    catch (Exception exp)
      {
      throw new Exception("ERROR: Unable to Retrieve Also Purchased Items - " + 
                                  exp.Message.ToString(), exp);
      }
    }

  if (ProductCount > 0)
     {
     WriteAlsoPurchased(_ProductId);              
     }
  else
     {
     WritePopularItems();
     }
}

"Ayrıca satın alındı" olduğunu belirledikten sonra yineleyiciyi sorgu tarafından döndürülen sonuçlara bağlayabiliriz.

//-------------------------------------------------------------------------------------+
private void WriteAlsoPurchased(int currentProduct)
{
  using (CommerceEntities db = new CommerceEntities())
        {
        try
          {
          var v = db.SelectPurchasedWithProducts(currentProduct);
          RepeaterItemsList.DataSource = v;
          RepeaterItemsList.DataBind();
          }
         catch (Exception exp)
          {
          throw new Exception("ERROR: Unable to Write Also Purchased - " + 
                                                          exp.Message.ToString(), exp);
          }
        }
}

"Ayrıca satın alınan" herhangi bir öğe yoksa kataloğumuzdan diğer popüler öğeleri görüntülememiz yeterlidir.

//--------------------------------------------------------------------------------------+
private void WritePopularItems()
{
  using (CommerceEntities db = new CommerceEntities())
    {
    try
      {
      var query = (from ProductOrders in db.OrderDetails
                   join SelectedProducts in db.Products on ProductOrders.ProductID 
                   equals SelectedProducts.ProductID
                   group ProductOrders by new
                         {
                         ProductId = SelectedProducts.ProductID,
                         ModelName = SelectedProducts.ModelName
                         } into grp
                   select new
                         {
                         ModelName = grp.Key.ModelName,
                         ProductId = grp.Key.ProductId,
                         Quantity = grp.Sum(o => o.Quantity)
                         } into orderdgrp
                   where orderdgrp.Quantity > 0
                   orderby orderdgrp.Quantity descending
                   select orderdgrp).Take(5);
                   
      LabelTitle.Text = "Other items you might be interested in: ";
      RepeaterItemsList.DataSource = query;
      RepeaterItemsList.DataBind();
      }
    catch (Exception exp)
      {
      throw new Exception("ERROR: Unable to Load Popular Items - " + 
                                                        exp.Message.ToString(), exp);
      }
    }
}

"Ayrıca Satın Alınan" öğeleri görüntülemek için ProductDetails.aspx sayfasını açın ve Ayrıca Satın Alınan denetimini Çözüm Gezgini'nden sürükleyerek işaretlemede bu konumda görünmesini sağlayın.

<table  border="0">
  <tr>
     <td>
       <img src='Catalog/Images/<%# Eval("ProductImage") %>'  border="0" 
                                                   alt='<%# Eval("ModelName") %>' />
     </td>
     <td><%# Eval("Description") %><br /><br /><br />  
         <uc1:AlsoPurchased ID="AlsoPurchased1" runat="server" />                 
     </td>
   </tr>
</table>

Bunu yaptığınızda ProductDetails sayfasının üst kısmındaki denetime bir başvuru oluşturulur.

<%@ Register src="Controls/AlsoPurchased.ascx" tagname="AlsoPurchased" tagprefix="uc1" %>

AlsoPurchased kullanıcı denetimi bir ProductId numarası gerektirdiğinden, sayfanın geçerli veri modeli öğesinde bir Eval deyimi kullanarak denetimimizin ProductID özelliğini ayarlayacağız.

Ürün kimlik bilgilerini vurgulayan ekran görüntüsü.

Şimdi derleyip çalıştırdığımızda ve bir ürüne göz attığımızda "Ayrıca Satın Alınan" öğeleri görürüz.

Satın alınan öğeleri gösteren ekran görüntüsü.