What's the deal with Databinder.Eval and Container.DataItem?

Reposting here for the benefit of asp.net developers and Google

The databinding expression <%# some expression %> is evaluated in the language of the page (VB, C#, etc.)  This can have a big impact on the current syntax, so be very careful when you are looking at docs for the language you are using.

 

Container.DataItem is a runtime alias for the DataItem for this specific item in the bound list.  For a grid which displays 10 rows of data, this is one row from the datasource.  The actual type of DataItem is determined by the type of the datasource.  For example, if the datasource is a Dataview, the type of DataItem is DataRowView.  If the type of the datasource is an array of strings, the type of DataItem is String.  If the datasource is a collection of strongly-typed objects (for example "Employees" objects), the type of DataItem is Employees.

 

Each of these cases requires a slightly different databinding expression, with further differences between VB and C#.  In every case, you want the databinding expression to produce a string that can be displayed in the page.

 

Here are some examples:

 

Array of Strings:

VB/C# <%# Container.DataItem %>

 

Field from DataView:

VB      <%# Container.DataItem("EmployeeName") %>

C#      <%# ((DataRowView)Container.DataItem)["EmployeeName"] %>

 

Property from a collection of objects:

VB      <%# Container.DataItem.CustomerName %>

C#      <%# ((Customer)Container.DataItem).CustomerName %>

 

Non-String property from a collection of objects:

VB      <%# CStr(Container.DataItem.CustomerID) %>

C#      <%# ((Customer)Container.DataItem).CustomerID.ToString() %>

 

 

As you can see the syntax is tricky, especially for C#, which requires explicit casting. So we've provided a DataBinder.Eval() helper method that figures out the syntax for you and formats the result as a string. It's really convenient, with a couple of caveats: it's late bound (uses reflection at runtime to figure out the data types), and it only supports basic data types in the fields: string, int, datetime, etc.

You can use Eval instead of DataBinder.Eval in ASP.net 2.0

  

DataBinder.Eval takes 2 or 3 arguments.  The first arg is the data object to bind to.  In the case of DataGrid, DataList and Repeater, Container.DataItem is the single row.  The second arg the string name of the field from the data object you which to display.  DataBinder.Eval uses these two pieces of information to work out the rest of the expression syntax.

 

An optional third argument is a .NET formatting string.  DataBinder.Eval will handle a single replacement for {0} only.  So the example below:

 

<a href='<%# "default.aspx?CategoryId=" + Cstr(Databinder.Eval(Container.DataItem, "ID"))%>'>


could be simplified to:


<a href='<%#  Databinder.Eval(Container.DataItem,"ID","default.aspx?CategoryId={0}" ) %>'>

 

Wrapping DataBinder.Eval in CStr() is unnecessary as the compiler will wrap the statement with a Convert.ToString like this:

control1.SetDataBoundString(0, Convert.ToString(DataBinder.Eval(item1.DataItem, "ID")));

 

Best of all, the Databinder.Eval syntax is the same for VB and C#. 


See this post for how you can use DataBinder.Eval from code behind

Susan Warren
11/30/2000 1:48:00 PM

Comments:
Scott Galloway
Worth mentioning the performance cost of this, in my own tests I've found around 20% performance loss in using DataBinder.Eval versus explicit casting. This can make a difference when binding large sets. My original post on this is here: http://www.mostlylucid.co.uk/archive/2003/12/09/664.aspx


References:

DataBinder.Eval Method


Other Posts

65 Comments

  • The problem with explicit casting is that if you change your data layer you have to go in every single page that uses it and change it. Using reflection doesn't have this problem.

  • Jerry, the same could be said about any strongly typed language - VBScript had variants only, made things really easy to change but you could get in a muddle really easily and end up with all sorts or runtime errors. I prefer the strongly typed approach and I have to say I don't find any increased maintainance costs associated with this.

  • how colud i do this
    &lt;%if(DataBinder.Eval(Container.DataItem,"WPID")&gt;0){%&gt;
    Requested Before.
    &lt;%}else{%&gt;
    &lt;INPUT id=chkImage type=checkbox value='&lt;%# DataBinder.Eval(Container.DataItem,"WPID") %&gt;' name=chkImage&gt;&amp;nbsp;Request Image
    &lt;%}%&gt;

  • Thanks... very helpful.

  • Thanks !!
    I learnt valuable information from ur article.Keep doing Such activities.
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Regards

  • Thanks... very useful article.

  • You just saved me with this one. Thanks!!

  • Is there any way I can evaluate one of those expressions? This is what I'd like to do:
    <%# If DataBinder.Eval(Container.DataItem, "DATAFIELD") "" Then
    Response.Write("something")
    End If %>

  • Description about this topic is easy understable and meaning full Thanks

  • Nice concise and good description. One thing was puzzling me though, how come theres no overloaded method that just takes a single parameter ie the Datafield string, and internally generates a reference to the Container.DataItem.

  • Very helpful solved my problem. Thanks

  • Thanks, good article

  • Thanks, that's a very easy to read and understand article and it helped fill in the gaps of my knowledge. i've been typing all this stuff out for years but have never both to find out what the code is actually doing. cheers for making it clearer.

  • Answering the question....
    <%# If DataBinder.Eval(Container.DataItem, "DATAFIELD") "" Then

    Response.Write("something")

    End If %>

    Try this....

  • Hi, when I put this code get the error message writen in title: dataitem is not a member of System.Web.UI.PageataItem.










    <asp:Label ID=lblLicniRacun runat=server Text='' />






    What is the problem?

  • Very nice article. Thanks

  • I tried this
    Text='&lt;%# If DataBinder.Eval(Container.DataItem, "CARRIER_NAME").Equals("") Then Response.Write("Some") End If %&gt;
    But found this Error:
    BC30201: Expression expected

  • Does Anyone know how to pass a whole Row into a Function? Something like this

    Function ParseData(ByVal oRow As RepeaterItem)
    Return oRow.Item("FieldName")
    End Function

    <asp:repeater....






  • Omprakash Pal:

    I usually put something like



    and then make a function:

    private string comparisonFunction(string criteria)
    {
    if (criteria<0)
    {
    return "this is less than 0";
    }
    else
    {
    return "this is greater than or equal to 0";
    }
    }

    or whatever. If you are thinking of adding controls to the page it would based on criteria like Mohamed Magdy was trying to do, I'd put that code in the event handler that would be the trigger for that control to appear. Put a place holder on the page (if there isn't a control you're adding it to) and use the placeholder.Controls.Add method.

    in the case that he mentioned above: you could add a label with the text that your want if one thing happened, otherwise you could add the checkbox.

  • Thanks for the clarification. This saved me some headaches. I was actually Googled for info on creating custom DataItem controls and found this article instead. After I finally created my custom object, I got a databinding error but was able to quickly fix it since I "accidentally" found this article previously.

    Thanks again.

  • Cheers, very helpful

  • Is it possible to bind 2 or 3 dimensional arrays to data controls If so, can u help me out with the syntax??

  • Does anyone know why

    works from within a Datalist (Datalist1) item to give me the ItemIndex in the aspx during binding, but the same code does not work in a child nested Datalist (Datalist2)? When used in a nested Datalist (Datalist2), gives me the ItemIndex of Datalist1.
    Cheers for any help.

  • Cheers, very helpful
    Ray Akkanson

  • very good article...keep it up

  • Just wanted to add my thanks.

  • Thanx it's very helpful

  • Nice article.
    To avoid databinder.eval which has the Reflection overhead to type the data, we could strongly type the Container.DataItem in VB.NET as follows



    In case of date formats,



  • This is what i have been wanting for months. Thx a lot !

  • Hello thanks for this article!

    One Question:

    Is it possible to give him informations through the eval?

    This works:
    Property from a collection of objects:
    VB

    But i need something like this:
    Container.DataItem.CustomerName("Information")

    I need a way to pass a string too! For example get the customer depending on the ID or something.
    E.G.: Container.DataItem.CustomerName("ID")

    Is that possible?

    Greetings!

  • Thank you this was very helpful!

  • helped me a lot..thanks

  • Hi,
    In DataBinder.Eval method, I have to pick up the column name which is created dynamically...How can I do this?

    e.g.
    1) When I am sure that my column name is Product_No, then I can use
    ''

    2) What if my column name is generated dynamically in the table, and I need to pick up that COLUMN NAME in this method???

    Please help

  • &lt;a href='&lt;%# &nbsp;Databinder.Eval(Container.DataItem,"ID","default.aspx?CategoryId={0}" ) %&gt;'&gt;

    How to pass one more query string?

  • Jiju this is for you


    <a href=''

  • For people who want to use if, else if else inside a <% using the Container.DataItem

    it won't work
    a workaround I created is this

    in your .cs file
    public static string PrintStuff(object obj){
    // if its a class
    YourClass x = (YourClass)obj;

    return YourClass.YourProperty;
    }

    my .aspx files only uses classes, all my DB stuff is behind the classes, so this worked ok for me

    maybe someone can put other alternative or using DataBase stuff

    hope this helps,

    Joe

  • I am developing a custom control, where I add Columns dynamically to an encapsulated DataGrid. I use following code to add a Template Column:


    Dim email As New TemplateColumn
    email.HeaderText = "Email"
    email.ItemTemplate = New UI.CompiledTemplateBuilder(New UI.BuildTemplateMethod(AddressOf Me.buildEmailTemplate))
    Me.grid.Columns.Add(email)

    Private Sub buildEmailTemplate(ByVal container As Control)
    Dim label As New Label

    container.Controls.Add(label)
    AddHandler label.DataBinding, New EventHandler(AddressOf Me.emailDataBinding)
    End Sub

    Private Sub emailDataBinding(ByVal sender As Object, ByVal e As EventArgs)
    Dim label As Label = CType(sender, Label)

    'label.Text = Common.Formatter.formatEmail(label.Parent.dataitem)
    End Sub



    Both buildEmailTemplate & emailDataBinding methods are invoked for each row, when the Grid is DataBound. However, I could not get to the DataItem property in any way, so that I can suitably format & display the email.

    So, how & where should I evaluate Container.DataItem for a dynamically added template column???

  • Why i cannot simply say &lt;%# Eval("DB_Field") %&gt;
    I mean this works for me but does it mean that i should avoid it and use Container.DataItem ??
    Thanks

  • Good stuff!

  • Hats of to you,Really Nice article which gives lot of information in a simple language.
    Keep doing this work...

  • &lt;div class="divCell ObsArabil"&gt;
    &lt;asp:Label runat="server" Text='&lt;%# DataBinder.Eval(Container.DataItem,"Comments")%&gt;' ID="lbleArabilComments" CssClass="Label SmallSize"&gt;
    &lt;/asp:Label&gt;
    &amp;nbsp;
    &lt;/div&gt;
    AND THE RESULT IS SOMETHING LIKE THIS
    28.08.2008:TEST
    HOW I MAKE TO WRITE JUST TEST?

  • Its a useful article..thanks

  • The article is a useful and easy to understand,it helped me a lot,i appreciate you to contiune and thank you.

  • Thank you very much,

    I understand how to use the function in databinder with container.DataItem

  • It is the simple concepts like this that are skipped by a lot of books and tutorials leading to misunderstanding when learning ASP.NET. Thanks.

  • I found out about this entry about 2 years ago (and saved my life back then), and I still come back to remember how to use it from time to time. Thanks!

  • I want to keep a if and else condition in the code below






    i have two radio button and on 1st radiobutton check i want to show only 1st coloumn data
    and on check of 2nd i want to show only 2nd column of data
    can anybody help me how to do it.
    please its urgent..

  • As a newbie to .NET coming from ASP Classic, I'm trying to use cimilar syntax to refer to columns in my data source but I am accustomed to using ordinal references, instead of column aliases. How can this be achieved in .NET using a data display control? I haven't found anything on it and I hope it didn't get axed since it's an overhead issue in so many ways.

  • nice, really nice!

  • Great post!! Finally found what I was looking for!

  • For those who asked the questions about dynamically added columns, did you find an answer?

    Specifically r_honey, my code's doing the same as yours and I can't find anywhere to access dataitem from any of my containing controls.

  • this is a very good article which is simply saying the conceptual things...it really helps...keep doing..all the best...

  • Hi, I have this code working - here it is - except for picking the data up on the next form. I want to use the SQL Identity function to select a record in a very small database table. I can see this at the bottom of IE, but I need to pick this up in the next page. Use of Request.Querystring("aptID") doesnt work as it returns null data. Is there a way of picking up this data?


  • This artical is really a excellect.

  • Please help me with the below code in C# .net, it's showing me error The type or namespace name 'DataRowView' could not be found (are you missing a using directive or an assembly reference?)

    Thanks in advance.

    ------------------------------------------------



    <asp:HyperLink ID="HyperLink2" runat="server" ImageUrl="~/Web/Images/edit2.gif" NavigateUrl=''>HyperLink


    <asp:HyperLink ID="Hyperlink1" runat="server" ImageUrl="~/Web/Images/edit.gif" NavigateUrl=''>HyperLink


  • awsome article.Thnx
    keep the good work gooing

  • This is great article with great Comments :)

  • DataBinder.Eval() has one more overoaded function which takes only columnname .Is it?

  • For everyone who's struggling with the IF statement, maybe this might help:

    <%# iif(DataBinder.Eval(Container.DataItem,"DATAFIELD") "", DataBinder.Eval(Container.DataItem,"DATAFIELD"), "")%>

    vb.net only tho..

  • For all the people pulling there hair out just to add a custom style to a repeater based on a value from a datatable, I have the answer.

  • Thank you, this is by far the best explanation of a tricky little bit of syntax.

  • tnX , it was so much helpful, tnx again

  • Just to expand on the last two comments about the VB IIF function...

    The IIF function does not use short-circuit evaluation. i.e. the following will generate a run-time error:
    IIf(divisor 0, number / divisor, 0)

    As of .NET2.0 you can and should use the new If Operator as follows (without generating a run-time error):
    If(divisor 0, number / divisor, 0)

    Note: IF, vs IIF; It is now comperable to C#'s ternary operator, below:
    condition ? first_expression : second_expression;





  • <a href=''>









    <a href=''>





  • A very good article. good concise information. writer not trying to cover "everything". another good thing is that, the conversation in the comments going on also gives u information.

  • Hi, anybody help me on the followin:



    I want to bind the expression dynamically. In my case the month August in DataItem.AugustTotal SLA is dynamically comes from a collection and i'm looping through the months.

    How can i do this?

Comments have been disabled for this content.