Sunday, 9 December 2012

Data View & Data Source Controls in Asp Net

Goals:
  • Present data source and data view controls.
Prerequisites:
  • The Northwind database installed in SQL Server instance. [Northwind's script]
Steps:
  1. Create a new ASP.NET Web Application project in Visual Studio.
  2. There are two types of server controls participate in the declarative data binding model:
    • Data source controls:
      • They do not render any user interface.
      • They act as an intermediary between a particular data store and other controls on the ASP.NET Web page.
      • They enable rich capabilities for retrieving and modifying data, including querying, sorting, paging, filtering, updating, deleting, and inserting.
      • Depending of the source of the data, one of the following controls can be used:
        • SqlDataSource - for any SQL database; it returns data as DataReader or DataSet objects
        • AccessDataSource - specialized version of the SqlDataSource control - only for Microsoft Access
        • LinqDataSource - for LINQ to SQL
        • EntityDataSource (3.5 SP1) - for Entity Framework
        • XmlDataSource - for data stored in XML files
        • SiteMapDataSource - special data source for a definition of web site's structure; used by navigational controls
        • ObjectDataSource - for special, custom logic of loading data (e.g. from services)
    • Data bound (data view) controls:
      • Controls designed to display bound data:
        • DetailsView
        • FormView
        • DataList
        • ListView
        • DataPager (it does not display the data, but allows to add paging for e.g. a ListView control)
      • Other controls that can be used to display bound data:
        • GridView
        • Repeater
  3. SqlDataSource
    • Add a SqlDataSource to the page.
    • Choose the 'Configure Data Source' task (available at the small button attached to the control in the Design mode). Choose the Northwind database and than the Customers table. We will allow the user to modify the displayed data, so using the Advanced button set the option of generating insert, update, and delete commands also:
    • The following markup code is generated:
      <asp:SqlDataSource ID="SqlDataSource1" runat="server"
          
      ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
          
      DeleteCommand="DELETE FROM [Customers] WHERE [CustomerID] = @CustomerID"
          
      InsertCommand="INSERT INTO [Customers] ([CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], [City], [Region], [PostalCode], [Country], [Phone], [Fax]) VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax)"
          
      SelectCommand="SELECT * FROM [Customers]"
          
      UpdateCommand="UPDATE [Customers] SET [CompanyName] = @CompanyName, [ContactName] = @ContactName, [ContactTitle] = @ContactTitle, [Address] = @Address, [City] = @City, [Region] = @Region, [PostalCode] = @PostalCode, [Country] = @Country, [Phone] = @Phone, [Fax] = @Fax WHERE [CustomerID] = @CustomerID">    <DeleteParameters>
              <asp:Parameter Name="CustomerID" Type="String" />     </DeleteParameters>
          <UpdateParameters>
              <asp:Parameter Name="CompanyName" Type="String" />         <asp:Parameter Name="ContactName" Type="String" />         <asp:Parameter Name="ContactTitle" Type="String" />         <asp:Parameter Name="Address" Type="String" />         <asp:Parameter Name="City" Type="String" />         <asp:Parameter Name="Region" Type="String" />         <asp:Parameter Name="PostalCode" Type="String" />         <asp:Parameter Name="Country" Type="String" />         <asp:Parameter Name="Phone" Type="String" />         <asp:Parameter Name="Fax" Type="String" />         <asp:Parameter Name="CustomerID" Type="String" />     </UpdateParameters>
          <InsertParameters>
              <asp:Parameter Name="CustomerID" Type="String" />         <asp:Parameter Name="CompanyName" Type="String" />         <asp:Parameter Name="ContactName" Type="String" />         <asp:Parameter Name="ContactTitle" Type="String" />         <asp:Parameter Name="Address" Type="String" />         <asp:Parameter Name="City" Type="String" />         <asp:Parameter Name="Region" Type="String" />         <asp:Parameter Name="PostalCode" Type="String" />         <asp:Parameter Name="Country" Type="String" />         <asp:Parameter Name="Phone" Type="String" />         <asp:Parameter Name="Fax" Type="String" />     </InsertParameters>
      </
      asp:SqlDataSource>
      Note that using the SqlDataSource control allows to create a web database application in seconds, but the generated code is quite hard to maintain - there are no data access and data logic layers, everything is mixed in the presentation layer.
  4. GridView
    • Add a GridView control to the page. As the DataSourceID, set the SqlDataSource1 control. Note that columns are automatically generated. Select also all checkboxes on the GridView Tasks window to enable additional options:
    • Run the page and note how easy was to create quite functional grid for presenting data for modification:
    • After a few more seconds and clicks (auto format, font, alignment of the pager), the page can change its appearance radically:
  5. LinqDataSource
    • Add a new 'LINQ to SQL Classes' item to the project:
    • Add all tables of the Northwind database to the new created DataClasses1.dbml file (drag them from the Server Explorer window):
    • Add a new page (i.e. a Web Form item) to the project.
    • Add a new LinqDataSource control to the page. Configure it using the 'Configure Data Source' task:

      (If the list of available context objects is empty, compile the project and try again.)
    • As in the previous example, we will allow the user to modify data:
    • We have chosen the Customers table, so name the control customersLinqDataSource.
    • Add another LinqDataSource named ordersLinqDataSource attached to the Orders table:
  6. DetailsView
    • Add a DetailsView control to the page. Set its DataSourceID to customersLinqDataSource and enable some additional features:
    • Run the page and check its functionality:
    • Let's display all orders of the selected customer at the right side using a grid:
      • Create a Table with 2 cells, put the DetailsView control to the left cell and the GridView control to the right one:
      • Set the ordersLinqDataSource control for the DataSourceID property of the GridView.
      • Run the page and note that data in the GridView is not filtered for the customer selected in the DetailsView control:
      • There is no need to write code to set the proper filter for the grid, it is enough to configure the ordersLinqDataSource control using the Visual Designer:
      • Make some cosmetic changes in the appearance of both visible controls and enjoy the result:
  7. FormView
    • The next step to improve our web application is to create a page that displays details of an order in a nice and easy to modify way.
    • Add a new page to the project, name it order.aspx.
    • Add a LinqDataSource control:
      • Name it orderLinqDataSource.
      • Configure it to get data from the Orders table of the DataClasses1 source. Be sure to enable modifying the data:
      • We want to display a single order, so we should filter the data source. As a filtering parameter we use OrderID which will be passed to the page in the query string:

        Be sure to set the default value for the parameter taken from the QueryString. Without this default value, the LinqDataSource control would try force converting nothing to an integer value and as a result the user would see an exception displayed on the page.
    • Add a FormView control to the page, set the DataSourceID property to orderLinqDataSource:
    • In most of data view controls, it is possible to define what should be displayed if there is no data. For the FormView control, it can be done by defining the EmptyDataTemplate:
    • Run the page:
    • If there is a proper OrderID parameter in the query string, the page displays data of the order:
    • To allow the user to jump directly to the order's details from the list of orders, set the Enable Selection options of the GridView control presenting orders to true:

      and add a handler for the SelectedIndexChanged event of the grid:
      protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
      {
          Server.Transfer(
      "~/order.aspx?OrderID=" + (int)GridView1.SelectedValue);
      }
      Note that transferring a request using the Server.Transfer method has some disadvantages. The better way would be adding a special column to the GridView control with manually created hyperlinks.
  8. ObjectDataSource
    • The last taks of this tutorial is to create a page displaying short information about customers in a form of a pageable list. Displayed information should contain: CustomerID, CompanyName, and number of orders.
    • Add to the project a class that will serve data (it will be used by the ObjectDataSource):
      using System;using System.Linq;using System.Data.Linq;using System.Collections;
      namespace DataControls
      {
          
      public class CustomersShortInfo     {
              
      private static DataClasses1DataContext customersDC;
              
      protected static DataClasses1DataContext CustomersDC
              {
                  
      get
                  {
                      
      if (customersDC == null)
                      {
                          customersDC =
      new DataClasses1DataContext();
                      }
                      
      return customersDC;
                  }
              }

              
      public static int GetCount()
              {
                  
      return CustomersDC.Customers.Count();
              }

              
      public static IEnumerable GetData(int startRowIndex, int maximumRows)
              {
                  
      var data =
                      (
      from c in CustomersDC.Customers
                      
      select new                  {
                           c.CustomerID,
                           c.CompanyName,
                           NumberOrders = c.Orders.Count
                       }
                      ).Skip(startRowIndex).Take(maximumRows);
                  
      return data;
              }
          }
      }
    • Add an ObjectDataSource control to the page. Configure it to use the GetData method of the CustomersShortInfo class to get data:
    • Modify the generated markup code to get such code:
      <asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
          
      TypeName="DataControls.CustomersShortInfo"
          
      EnablePaging="True"
          
      SelectMethod="GetData" SelectCountMethod="GetCount">
      </
      asp:ObjectDataSource>
      (Parameters of the GetData method are used automatically when paging is enabled, explicit declaration would cause problems.)
  9. ListView
    • Add a ListView control to the page.

      If there is no such control on the Toolbox, do not worry, just start typing '<asp:ListView' in the Source view of the page.
    • To make it work, the LayoutTemplate and ItemTemplate of the ListView control must be set. Additionally, because we expect paging parameters in the GetData method, a DataPager control must be used:
      <asp:ListView ID="ListView1" runat="server" DataSourceID="ObjectDataSource1">
          <LayoutTemplate>
              <div runat="server" id="lstProducts">
                  <div runat="server" id="itemPlaceholder" />         </div>
              <asp:DataPager ID="DataPager1" runat="server" PageSize="5">
                  <Fields>
                      <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" />             </Fields>
              </asp:DataPager>
          </LayoutTemplate>
          <ItemTemplate>
              <div >             ID: <asp:Label ID="Label1" runat="server" Text='<%# Eval("CustomerID")%>' /><br />             Company name: <asp:Label ID="Label2" runat="server" Text='<%# Eval("CompanyName")%>' /><br />             Number of orders: <asp:Label ID="Label3" runat="server" Text='<%# Eval("NumberOrders")%>' />         </div>
              <br />     </ItemTemplate>
      </
      asp:ListView>
    • Run the page:
    • The appearance of data can be almost freely modified, e.g.:

       
      <asp:ListView ID="ListView2" runat="server" DataSourceID="ObjectDataSource1">
          <LayoutTemplate>
              <asp:DataPager ID="DataPager1" runat="server" PageSize="20">
                  <Fields>
                      <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" />             </Fields>
              </asp:DataPager>
              <br />         <div runat="server" id="lstProducts">
                  <span runat="server" id="itemPlaceholder"/>
              </div>
          </LayoutTemplate>
          <ItemTemplate>
              <div style="float: left; width: 200px; margin: 20px 20px 20px 20px;">
                  ID: <asp:Label ID="Label1" runat="server" Text='<%# Eval("CustomerID")%>' /><br />             Company name: <asp:Label ID="Label2" runat="server" Text='<%# Eval("CompanyName")%>' /><br />             Number of orders: <asp:Label ID="Label3" runat="server" Text='<%# Eval("NumberOrders")%>' />         </div>
          </ItemTemplate>
      </
      asp:ListView>
[Source code]

No comments :