why asp.net binding expression shows nothing - asp.net

I'm just testing a simple databind expression with:
<div>
Now: <%# DateTime.Now.ToString()%>
</div>
According to MSDN:
http://msdn.microsoft.com/en-us/library/bda9bbfx(VS.71).aspx
literal text <%# data-binding expression %>
should work.
When I compile, it's OK but I got a blank instead of Now DateTime.
What's wrong ?

You must call a DataBind method. In this case, add a call to the Page.DataBind in the page's load event. The DataBind method is not called automatically. You must call it for the page or for specific controls.
ASP.NET data binding overview at http://support.microsoft.com/kb/307860

Related

“The Controls collection cannot be modified because the control contains code blocks”

While trying to insert controls in my page with the following block of code, i got this exception
The Controls collection cannot be modified because the control
contains code blocks
Literal lite=new Literal();
lite.Text = #"<div class='cookieLaw_slidesharey'><a id='cookieLaw_slideshare' href='#'><img src='/img/content/cookielaw_slideshare.jpg'/></a></div>";
Control control = this.FindControl("PlaceHolder");
control.Controls.AddAt(0,lite);
I tried to follow the advices written in this thread:
"The Controls collection cannot be modified because the control contains code blocks"
Which are basically:
replacing <%= %> with <%# %>
And adding
Page.Header.Databind() in the page load
But i get the following exception:
Object reference not set to an instance of an object.
Thank you for your help.
PS: i'm using .NET 3.5
Check if your "PlaceHolder" has a runat=server attribute. That should already help. You can address that control by it's id then instead of using FindControl.
The reason why your Page.Header.Databind() is not working is probably because you don't have a head section with the runat=server like in the example you copied from. They were adding controls in the header there which can be slightly different.

ASP.Net <%# %> and <%= %> rules?

Can someone explain to me the rules around what can and cannot be evaluated/inserted into markup using the <%# %> and <%= %> tags in asp.net?
When I first discovered I could inject code-behind variables into mark-up using <%= I thought 'great'. Then I discovered that if such tags are present you can then not add to the controls collection of the page (that's a whole different question!). But <%# tags are ok.
Is there a way I can inject a code-behind variable or function evaluation into the page using <%# ? Thanks.
<%%> are code blocks. You can put any server side code in them. This is a shortcut for <script runat="server"></script>.
<%=%> is for outputting strings. This is a shortcut for <script runat="server">Response.Write()</script>.
See here for more detail about <%%> and <%=%>.
<%#%> are used for data binding expressions.
See the index page for asp.net Page syntax.
The <%# inline tag is used for data binding, so if you want to use a code-behind variable inside it, you will have to bind the page or control the variable resides in:
Page.DataBind();
You can include this statement in the Page_Load or Page_PreRender event.
See this article for more information about the use of inline tags in ASP.Net, and this article for more about server-side databinding.

Binding custom class property of an ASP.NET control from ASCX markup

I have an ASCX that inherits from a WebControl that has a 'CustomConfiguration' property of type CollectionConfigurationItem. This configuration gets set elsewhere in the code, so by the time it gets to the ASCX it is set up to how I wish to use the data. At this point I'd like to render out another control using this configuration, like so:
<modules:DataModule runat="server" CustomConfiguration="<%# Model.CategoryListConfiguration %>" />
However, breaking into DataModule always results in 'CustomConfiguration' being null, which is the default value for the property. I've tried adding a Bindable attribute to the property but to no avail, and when I set an EventHandler for the DataBinding event on the DataModule it doesn't even get called.
How can I set this custom-class-typed property from the markup or, failing that what's the second-best method of getting this to work? Thanks for any light you can shed!
When you use the <%# %> syntax, it doesn't get executed until you databind the control. Try calling:
yourDataModuleID.DataBind();
e.g. from your Page_Init method.

How do you use extension methods in Web form data-binding expressions?

Has anyone successfully used extension methods in data-binding expressions?
Say I have an extension method called "GetName" attached to "MyClass".
In the code behind, I have verified this works:
MyClass myObject = new MyClass();
MyClass.GetName();
However, in a Web form, I try this:
<%# Import Namespace="My.Namespace" %>
Then, in the ItemTemplate of a Repeater:
<%# ((MyClass)Container.DataItem).GetName() %>
Visual Studio is cool with this, Intellisense agrees with everything, and the project builds. But when I run it, I get:
Compilation Error
'My.Namespace.MyClass' does not contain a definition for 'GetName'
So, the code-behind will accept the extension method, but not the Web form. I suspect it's a name-spacing issue, but I've imported the same namespace in both places.
The databinding syntax in aspx/ascx files is notoriously picky. There is a certain amount of parsing that goes on, in particular in this binding area. Look at this example:
This works:
<%# String.Format("{0:C}", DataBinder.Eval("Foo")) %>
But this doesn't:
<%# String.Format("{0:C}", Bind("Foo")) %>
Why? Because while DataBinder.Eval is a real method, Bind is not. Yes, really, it's just a token recognized by the expression binder/parser - it's not actually compiled. I think DataBinder.Eval is probably special-cased for compatibility with ASP.NET 1.1/1.0.
Just to complete the example, the correct way to bind the above expression is to use:
<%# Bind("Foo", "{0:C}") %>
Hope this helps,
Clarification Edit: The C# compiler understands extension methods. The asp.net expression parser does not.
If you're binding to a collection and want to leverage the strongly typed class MyClass, you can perform the extension in a function in codebehind.
your repeater can use
<%# GetObjectName((MyClass)Container.DataItem) %>
Your CodeBehind will have:
protected string GetObjectName(MyClass obJect)
{
return obJect.GetName();
}
Don't forget to import the namespace of your extension module.

What other objects are accessible inside <%# %> tags in aspx?

I run into similar codes like this all the time in aspx pages:
<asp:CheckBox Runat="server" ID="myid" Checked='<%# DataBinder.Eval(Container.DataItem, "column").Equals(1) %>'>
I was wondering what other objects I have access to inside of that <%# %> tag. How come DataBinder.Eval() and Container.DataItem are not visible anywhere inside .CS code?
Within <%# %> tags you have access to
Anything that is visible in your code-behind class (including protected methods and properties).
Anything declared on the aspx page using <#import #>.
Anything passed in as the event arguments when the ItemDataBound event is fired (e.g. RepeaterItemEventArgs, DataListItemEventArgs, etc).
Container is actually a wrapper for RepeaterItemEventArgs.Item, DataListItemEventArgs.Item, etc. So you can actually access it in code behind within your ItemDataBound events as e.Item (e normally being the event arguments parameter name).
DataBinder is also accessible in code behind by using System.Web.UI.DataBinder.
On a side note, casting the Container.DataItem is preferred over using Eval. Eval uses reflection so there's an overhead there. In VB.NET it would be something like
<%#DirectCast(Container.DataItem, DataRow)("some_column")%>
Or C#
<%#((DataRow)Container.DataItem)["some_column"].ToString()%>
I believe you have access to anything within scope of the page class, though the results of the expression are converted to a string, so you can't embed conditional expressions the way you can with "<%" expression holes.
Here is a nice blog post which dives under the covers of the generated ASPX class.
Hope this helps.
<%# is specific to inline ASPX databinding like the link ckramer posted suggests.
How come DataBinder.Eval() and Container.DataItem are not visible anywhere inside .CS code?
To access the binding item in codebehind you would need to set up an ItemDataBound event.
ASP.NET generates a subclass of TemplateControl for each occurence of a template. Databinding statements are expressions used in a method inside that class. Thus, you can call any public/protected instance method on TemplateControl. See any example that uses XPath, as those will use the XPath and XPathSelect methods; Eval, XPath and XPathSelect are all instance methods on TemplateControl.
DataBinder is actually a separate class, and Eval is a public static method on it; it's in System.Web.UI. DataBinder.Eval and plain Eval are not directly related though they do very similar things visibly.
I believe that "Container" is actually a local variable or parameter where databinding statements are compiled. I can't remember its type at the moment.
using <%# %> actually means that code inside this block will execute when page.DataBind() method is being executed. Thus you can access anything at that point accessible as protected/public to that particular page/control.
Great example
<%#((System.Data.DataRow)Container.DataItem)["ColumnName"].ToString()%>

Resources