Tuesday, August 14, 2012

Changes in webforms 4.5

ASP.NET Web Forms Changes:

Strongly Typed Data Controls


In ASP.NET 4.5, Web Forms includes some improvements for working with data. The first improvement is strongly typed data controls. For Web Forms controls in previous versions of ASP.NET, we display a data-bound value using Eval and a data-binding expression:
eg: <asp:Repeater runat="server" ID="customers">
        <ItemTemplate>
            <li>
                First Name: <%# Eval("FirstName")%>

                Last Name: <%# Eval("LastName")%>

            </li>
        </ItemTemplate>
    </asp:Repeater>

For two-way data binding, we use Bind:
<asp:FormView runat="server" ID="editCustomer">
    <EditItemTemplate>
        <div>
            <asp:Label runat="server" AssociatedControlID="firstName">
                First Name:

            <asp:TextBox ID="firstName" runat="server"
                Text='<%#Bind("FirstName") %>' />
        </div>
<EditItemTemplate>
<asp:FormView>
        <div>
            <asp:Label runat="server" AssociatedControlID="lastName">
                First Name:</asp:Label>
            <asp:TextBox ID="lastName" runat="server">

                Text='<%#BindItem.LastName %>' />

At run time, these calls use reflection to read the value of the specified member and then display the result in the markup. This approach makes it easy to data bind against arbitrary, unshaped data.

To address this issue, ASP.NET 4.5 adds the ability to declare the data type of the data that a control is bound to. We do this using the new ItemType property. When we set this property, two new typed variables are available in the scope of data-binding expressions: Item and BindItem. Because the variables are strongly typed, we get the full benefits of the Visual Studio development experience.

The following example shows for the Item member:

<asp:Repeater runat="server" ID="customer" ModelType="WebApplication.Customer">
<itemTemplate>
    First Name: <%# Item.FirstName %><br/>
    Last Name: <%# Item.LastName %>
</itemTemplate>
</asp:Repeater>

For two way binding "BindItem" can be used in place of Item.

Model Binding


Model binding extends data binding in ASP.NET Web Forms controls to work with code-focused data access. It incorporates concepts from the
ObjectDataSource control and from model binding in ASP.NET MVC.
To configure a data control to use model binding to select data, you set the control's SelectMethod property to the name of a method in the page's code. The data control calls the method at the appropriate time in the page life cycle and automatically binds the returned data. There's no need to explicitly call the DataBind method.

In the following example, the GridView control is configured to use a method named GetCategories:

<asp:GridView ID="categoriesGrid" runat="server" ItemType="WebApplication1.Model.Category"
    SelectMethod="GetCategories" AutoGenerateColumns="false">
    <Columns>
        <asp:BoundField DataField="CategoryID" HeaderText="ID" />
        <asp:BoundField DataField="CategoryName" HeaderText="Name" />
        <asp:BoundField DataField="Description" HeaderText="Description" />
        <asp:TemplateField HeaderText="# of Products">
            <ItemTemplate><%# Item.Products.Count %></ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

Here  we have created "GetCategories" method in code behind file which is without any parameters and returning an IEnumerable or IQueryable object. If the new ItemType property is set (which enables strongly typed data-binding expressions, as explained under Strongly Typed Data Controls earlier), the generic versions of these interfaces should be returned — IEnumerable or IQueryable, with the T parameter matching the type of the ItemType property (for example, IQueryable).

Code behind method defination of "GetCategories":
public IQueryable
GetCategories()
{
    var db = new Northwind();
    return db.Categories.Include(c => c.Products);
 }

Any query can be placed on returned IEnumerable and IQueryable objects eg. sorting, paging etc.

Filtering by values from a control

Suppose we want to extend the example to let the user choose a filter value from a drop-down list. Add the following drop-down list to the markup and configure it to get its data from another method using the SelectMethod property:

<asp:Label runat="server" AssociatedControlID="categories"
    Text="Select a category to show products for: " />
<asp:DropDownList runat="server" ID="categories"
    SelectMethod="GetCategories" AppendDataBoundItems="true"
    DataTextField="CategoryName" DataValueField="CategoryID"
    AutoPostBack="true">
  <asp:ListItem Value="" Text="- all -" />
</asp:DropDownList>

<asp:GridView ID="productsGrid" runat="server" DataKeyNames="ProductID"
    AllowPaging="true" AllowSorting="true" AutoGenerateColumns="false"
    SelectMethod="GetProducts" >
    <Columns>
        <asp:BoundField DataField="ProductID" HeaderText="ID" />
        <asp:BoundField DataField="ProductName" HeaderText="Name"                  
             SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Unit Price"
             SortExpression="UnitPrice" />
        <asp:BoundField DataField="UnitsInStock" HeaderText="# in Stock"
             SortExpression="UnitsInStock" />
    </Columns>
    <EmptyDataTemplate>
         No products matching the filter criteria were found

</asp:GridView>

In the page code, add the new select method for the drop-down list:

public IQueryable<Category>
GetCategories()
{
    return _db.Categories;
 }

Finally, update the GetProducts select method to take a new parameter that contains the ID of the selected category from the drop-down list:

public IQueryableGetProducts([QueryString("q")] string keyword,[Control("categories")] int? categoryId)
 {
    IQueryable query = _db.Products;
 
    if (!String.IsNullOrWhiteSpace(keyword))
    {
        query = query.Where(p => p.ProductName.Contains(keyword));
    }
    if (categoryId.HasValue && categoryId > 0)
    {
        query = query.Where(p => p.CategoryID == categoryId);
    }
    return query;
 }

Now when the page runs, users can select a category from the drop-down list, and the GridView control is automatically re-bound to show the filtered data. This is possible because model binding tracks the values of parameters for select methods and detects whether any parameter value has changed after a postback. If so, model binding forces the associated data control to re-bind to the data.

HTML Encoded Data-Binding Expressions


we can now HTML-encode the result of data-binding expressions. Add a colon (:) to the end of the <%# prefix that marks the data-binding expression:

<asp:TemplateField HeaderText="Name">
    <ItemTemplate><%#: Item.Products.Name %></ItemTemplate>
</asp:TemplateField>

Unobtrusive Validation


We can now configure the built-in validator controls to use unobtrusive JavaScript for client-side validation logic. This significantly reduces the amount of JavaScript rendered inline in the page markup and reduces the overall page size. Wecan configure unobtrusive JavaScript for validator controls in any of these ways:
Globally by adding the following setting to the element in the Web.config file:

<add name="ValidationSettings:UnobtrusiveValidationMode" value="WebForms" />

HTML5 Updates


Some improvements have been made to Web Forms server controls to take advantage of new features of HTML5:

    The TextMode property of the TextBox control has been updated to support the new HTML5 input types like email, datetime, and so on.
    The FileUpload control now supports multiple file uploads from browsers that support this HTML5 feature.
    Validator controls now support validating HTML5 input elements.
    New HTML5 elements that have attributes that represent a URL now support runat="server". As a result, we can use ASP.NET conventions in URL paths, like the ~ operator to represent the application root
 (for example, <video runat="server" src="~/myVideo.wmv" />).
    The UpdatePanel control has been fixed to support posting HTML5 input fields.
                Text='<%# Bind("LastName") %>' />
        </div>
        <asp:Button runat="server" CommandName="Update"/>
    </EditItemTemplate>
</asp:FormView>