Sunday, August 15, 2010

'Two way data binding' Vs 'one way data binding' in asp.net - Bind() Vs Eval()

Eval(...) - One way
Bind(...) - Two way

Asp.net databinder works with reflection. In simple terms Eval("PropertyName") get the value from the data object and put it on the relvent control, while Bind("PropertyName") get the value from the data object put it in the control and one the update event it get the updated control value pass it to the relevent method to update.
Very simple example:
Person class:
public class Person
{
    public string Name { getset; }
    public List<Person> GetPeople()
    {
        List<Person> people = new List<Person>();
        for (int i = 0; i < 10; i++)
            people.Add(new Person { Name = "Person " + i });
        return people;
    }
    public void SetPerson(string Name)
    {
 
    }
}
Markup:
<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head2" runat="server">
</head>
<body>
    <form id="form2" runat="server">
        <div>
            <asp:GridView 
                runat="server" 
                ID="grvPeople" 
                AutoGenerateColumns="false" 
                DataSourceID="odsPeople" 
                AutoGenerateEditButton="true">
                <Columns>
                    <asp:TemplateField>
                        <EditItemTemplate>
                            <asp:TextBox runat="server" ID="txtItem" Text='<%# Bind("Name") %>'></asp:TextBox>                        
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label runat="server" ID="lblPerson" 
                            Text='<%# string.Format("Mr. {0}", Eval("Name")) %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
            <asp:ObjectDataSource 
                ID="odsPeople" 
                runat="server" 
                TypeName="ActiveTest.Person"
                SelectMethod="GetPeople" 
                UpdateMethod="SetPerson">
            </asp:ObjectDataSource>        
        </div>
    </form>
</body>
In this example, As you can see
  1. I have object datasource "odsPeople" which has the type of 'Person'
  2. I have Select Method as public method GetPeople
  3. I have Update Method as public method SetPerson
Number of parameters pass to SetPerson method is equal to the number of Bind(...) expressions. Parameter names are exactly equal to bound property name.In this case 'Name'
Where to use:
In a simple page like this, where we dont have templated or templated repeater controls like Repeater, GridView, FormView, DetailsView etc, using Bind(...) method does not make any sence,
<%@ Page Language="C#" %>
<html>
<head id="Head2" runat="server">
    <script runat="server">
        public Person Person { getset; }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (!this.IsPostBack)
            {
                this.Person = new Person();
                this.txtName.DataBind();
            }
        }        
    </script>
</head>
<body>
    <form id="form2" runat="server">
        <div>
            <asp:TextBox runat="server" ID="TextBox1" Text='<%# Bind("Person.Name") %>' />
        </div>
    </form>
</body>
</html>
Because it is very simple like this.
<%@ Page Language="C#" %>
<html>
<head id="Head1" runat="server">
    <script runat="server">
        public Person Person { getset; }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (!this.IsPostBack)
            {
                this.Person = new Person();
                this.txtName.Text = "Save";
            }
        }      
        protected void Save(object sender, EventArgs e)
        {
            string name = this.txtName.Text;
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:TextBox runat="server" ID="txtName" />
            <asp:Button runat="server" ID="btnSave" Text="Save" OnClick="Save" />
        </div>
    </form>
</body>
</html> 

With LINQ to SQL:
<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head2" runat="server">
</head>
<body>
 <form id="form2" runat="server">
 <div>  
  <asp:GridView 
   runat="server" 
   ID="GridView1" 
   AutoGenerateColumns="False" 
            AutoGenerateEditButton="true" 
            AutoGenerateSelectButton="true" 
            AutoGenerateDeleteButton="true"          
            DataKeyNames="Id" 
            DataSourceID="ldsLinqDataSource">
            <Columns>
                <asp:BoundField DataField="Id" 
                    HeaderText="Id" InsertVisible="False" 
                    ReadOnly="True" SortExpression="Id" />
                <asp:TemplateField>
                    <ItemTemplate>
                        <asp:Label runat="server" ID="lblUrl" Text='<%# Eval("Url") %>' />
                    </ItemTemplate>
                    <EditItemTemplate>
                        <asp:TextBox runat="server" ID="txtUrl" Text='<%# Bind("Url") %>' />
                    </EditItemTemplate>
                </asp:TemplateField>
            </Columns>
  </asp:GridView>
     <asp:LinqDataSource 
            ID="LinqDataSource1" 
            runat="server" 
            ContextTypeName="ActiveTest.ActiveTestDataContext" 
            EntityTypeName="" 
            TableName="Projects" 
            EnableUpdate="true"
            EnableDelete="true" 
            EnableInsert="true">
        </asp:LinqDataSource>
 </div>
 </form>
</body>
</html>
 Additional information:

Eval(...) - One way

Asp.net 2.0+

Eval("PropertyName")

<%# Eval("Name") %>

Supports any line manupulation and formatting
<%# string.Format("Mr. {1}",Eval("Name") %>


Eval("PropertyName", "FormatString");

<%# Eval("Name", "Mr. {1}") %>

Bind(...) - Two way
Asp.net 2.0+

Bind("PropertyName")
Only supports
<%# Bind("Name") %>
Does not support line manupulation and formatting
<%# string.Format("Mr. {1}",Bind("Name") %> is invalid

Bind("PropertyName","Formatting");

<%# Bind("Name", "Mr. {1}") %>

References:
  1. VB Two-Way Databinding in a FormView Edit Template
  2. How ASP.NET databinding deals with Eval() and Bind() statements
  3. Asp.net Eval() and Bind() expressions in data bound controls like GridView and DetailsView

No comments:

Azure Storage Account Types

Defferent Types of Blobs Block blobs store text and binary data. Block blobs are made up of blocks of data that can be managed individually...