Anti Pattern – Smart UI Part 3

Now that we have added two columns.. now its time to add code behind code…

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if(e.Row.RowType==DataControlRowType.DataRow)
            {
                decimal RRP = decimal.Parse(((System.Data.DataRowView)(e.Row.DataItem))["RRP"].ToString());
                decimal SellingPrice = decimal.Parse(((System.Data.DataRowView)(e.Row.DataItem))["SellingPrise"].ToString());

                Label lblSavings = (Label)e.Row.FindControl("lblSavings");
                Label lblDiscount = (Label)e.Row.FindControl("lblDiscount");

                lblSavings.Text = displaySavings(RRP,SellingPrice);
                lblDiscount.Text = displayDiscount(RRP, SellingPrice);

            }
        }

        private string displayDiscount(decimal rRP, decimal sellingPrice)
         {
            string discoutText = "";
            if(rRP>sellingPrice)
            {
                discoutText = string.Format("{0:c}", (rRP - sellingPrice));
            }
            return discoutText;
        }

        private string displaySavings(decimal rRP, decimal sellingPrice)
        {
            string savingsText = "";

            if(rRP>sellingPrice)
            {
                savingsText = (1 - (sellingPrice / rRP)).ToString("#%");
            }
            return savingsText;
        }

Add the above three methods..to display savings and discount..if you run our code this is how it looks like

  • what have done ..??
  • The GridView1_RowDataBound method is called when each data row is bound to data in the
    GridView control. The method obtains the RRP and selling price and uses DisplayDiscount and DisplaySavings methods to work out the correct discount. Then it updates the corresponding label server controls.

    Broken things

    • Violating Single Responsibility Principle – The page is not only taking the responsibility of the business logic(we are caliculating savings and discount here) and also responsible for the data access requirements
    • Its hard to test.. the way its implemented now…

    Now that we have put business logic in the code behind file… lets add some more business logic to it..

  • This is the use case- trade discount to be applied to the prices so that they reflect an extra 5 percent of savings( we are going to apply trade discount via drop down).
  • Anti Pattern – Smart UI Part 2

    Lets start building SmartUI application

    • Fire up Visual Studio and create a new blank solution named ASPPatterns.Chap3.SmartUI
      and add a new web application to it named ASPPatterns.Chap3.SmartUI.Web
    • add a new SQL express database to
      the project by right-clicking on the web site and selecting Add ➪ New Item and selecting a SQL Server Database. Name the database Shop.mdf.
    • Now you need to add a table Products to the database
    • Add the data to the table
    • With the table created, you can simply drag and drop it onto the Default.aspx page.This automatically creates a GridView and adds a SQLDataSource control to the page.You should now be able to run the web application and see all the products listed
      from the database

    This is how now code looks like

    <body>
        <form id="form1" runat="server">
        <div>
        
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ProductId" DataSourceID="SqlDataSource1" EmptyDataText="There are no data records to display.">
                <Columns>
                    <asp:BoundField DataField="ProductId" HeaderText="ProductId" ReadOnly="True" SortExpression="ProductId" />
                    <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" />
                    <asp:BoundField DataField="RRP" HeaderText="RRP" SortExpression="RRP" />
                    <asp:BoundField DataField="SellingPrise" HeaderText="SellingPrise" SortExpression="SellingPrise" />
                </Columns>
            </asp:GridView>
            <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ShopConnectionString1 %>" DeleteCommand="DELETE FROM [Products] WHERE [ProductId] = @ProductId" InsertCommand="INSERT INTO [Products] ([ProductId], [ProductName], [RRP], [SellingPrise]) VALUES (@ProductId, @ProductName, @RRP, @SellingPrise)" ProviderName="<%$ ConnectionStrings:ShopConnectionString1.ProviderName %>" SelectCommand="SELECT [ProductId], [ProductName], [RRP], [SellingPrise] FROM [Products]" UpdateCommand="UPDATE [Products] SET [ProductName] = @ProductName, [RRP] = @RRP, [SellingPrise] = @SellingPrise WHERE [ProductId] = @ProductId">
                <DeleteParameters>
                    <asp:Parameter Name="ProductId" Type="Int32" />
                </DeleteParameters>
                <InsertParameters>
                    <asp:Parameter Name="ProductId" Type="Int32" />
                    <asp:Parameter Name="ProductName" Type="String" />
                    <asp:Parameter Name="RRP" Type="Decimal" />
                    <asp:Parameter Name="SellingPrise" Type="Decimal" />
                </InsertParameters>
                <UpdateParameters>
                    <asp:Parameter Name="ProductName" Type="String" />
                    <asp:Parameter Name="RRP" Type="Decimal" />
                    <asp:Parameter Name="SellingPrise" Type="Decimal" />
                      <asp:Parameter Name="ProductId" Type="Int32" />
                </UpdateParameters>
            </asp:SqlDataSource>
        
        </div>
        </form>
    </body>
    

    This is how our page looks like..

  • Now add extra columns to the grid to show discount and savings. we will add these two columns as template columns.and also include OnRowDataBound event
  • This now the modified code after adding template columns..

    <body>
        <form id="form1" runat="server">
        <div>
        
            <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
                DataKeyNames="ProductId"
                DataSourceID="SqlDataSource1"
                EmptyDataText="There are no data records to display." 
                OnRowDataBound="GridView1_RowDataBound">
                <Columns>
                    <asp:BoundField DataField="ProductId" HeaderText="ProductId" ReadOnly="True" SortExpression="ProductId" />
                    <asp:BoundField DataField="ProductName" HeaderText="ProductName" SortExpression="ProductName" />
                    <asp:BoundField DataField="RRP" HeaderText="RRP" SortExpression="RRP" />
                    <asp:BoundField DataField="SellingPrise" HeaderText="SellingPrise" SortExpression="SellingPrise" />
                    <asp:TemplateField HeaderText="Discount">
                        <ItemTemplate>
                            <asp:Label runat="server" ID="lblDiscount"></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Savings">
                        <ItemTemplate>
                            <asp:Label runat="server" ID="lblSavings"></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
            <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ShopConnectionString1 %>" DeleteCommand="DELETE FROM [Products] WHERE [ProductId] = @ProductId" InsertCommand="INSERT INTO [Products] ([ProductId], [ProductName], [RRP], [SellingPrise]) VALUES (@ProductId, @ProductName, @RRP, @SellingPrise)" ProviderName="<%$ ConnectionStrings:ShopConnectionString1.ProviderName %>" SelectCommand="SELECT [ProductId], [ProductName], [RRP], [SellingPrise] FROM [Products]" UpdateCommand="UPDATE [Products] SET [ProductName] = @ProductName, [RRP] = @RRP, [SellingPrise] = @SellingPrise WHERE [ProductId] = @ProductId">
                <DeleteParameters>
                    <asp:Parameter Name="ProductId" Type="Int32" />
                </DeleteParameters>
                <InsertParameters>
                    <asp:Parameter Name="ProductId" Type="Int32" />
                    <asp:Parameter Name="ProductName" Type="String" />
                    <asp:Parameter Name="RRP" Type="Decimal" />
                    <asp:Parameter Name="SellingPrise" Type="Decimal" />
                </InsertParameters>
                <UpdateParameters>
                    <asp:Parameter Name="ProductName" Type="String" />
                    <asp:Parameter Name="RRP" Type="Decimal" />
                    <asp:Parameter Name="SellingPrise" Type="Decimal" />
                      <asp:Parameter Name="ProductId" Type="Int32" />
                </UpdateParameters>
            </asp:SqlDataSource>
        
        </div>
        </form>
    </body>