ASP.NET custom control rendering before <%= %> code executes to populate property - asp.net

I have a custom control that exposes a property. When I set it using a fixed value, everything works correctly. But if I try to set its value using the <%= %> tags, it goes a little whacky:
<cc:CustomControl ID="CustomControl" runat="server" Property1='<%= MyProperty %>' />
<%= MyProperty %>
When this gets rendered, the <%= MyProperty %> tag underneat the custom control is rendered as I expect (with the value of MyProperty). However, when I step into the Render function of the CustomControl, the value for Property1 is literally the string "<%= MyProperty %>" instead of the actual underlying value of MyProperty.

You control is initialized from the markup during OnInit. So if that syntax worked, it wouldn't have the effect you wanted anyway, since MyProperty would be evaluated during OnInit and not at render time (like it is with the second usage).
You want to use the data binding syntax instead:
<cc:CustomControl ID="CustomControl" runat="server" Property1='<%# MyProperty %>' />
Just make sure to call DataBind() on the container (Page, UserControl, etc).
Alternatively, you can set the property in your code behind:
CustomControl.Property1 = MyProperty;

Try <%# MyProperty %> in the CustomControl and see if that works.

Related

Using Code Nuggets as property values

I have the following code
<asp:Content ID="Content1" runat="server">
<asp:Label runat="server" ID="Label1" Text="<%= MyHelperClass.Value%>"></asp:Label>
<%= MyHelperClass.Value%>
</asp:Content>
The Label doesn't work, it has the Text <%= MyHelperClass.Value%> the next row returns the expected value.
Question: can i use those code nuggets to set values of the property of an control?
Why it's working outside and not with Control?
Well <%= %> is called Content Code Nuggets because they inject content in the html which is sent by server to browser. It does the work of Reponse.Write. We use this mainly to call any code written in code behind file for example, you have a simple method in your code behind:-
public string UserCity()
{
return "London";
}
Then you can call it from aspx page like this:-
You live in <%= UserCity() %>.
Content code nuggets used to inject the html to response at the last in PreRender event and thus it's called late binding. This is the main reason why it is NOT working with your control.
How to fix this?
You can use the data binding code nuggets (<%# %>). These are used with DataBound controls but you can force the Page's DataBound or control's DataBound method to bind your control like this:-
<asp:Label runat="server" ID="Label1" Text="<%# MyHelperClass.Value%>"></asp:Label>
Call DataBind method in code behind:-
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Page.DataBind();
}
}

A tricky way to using <%# Bind %> in ASP.NET

In ASP.NET, I can use <%# Bind %> to achieve two-way data binding, then the data source control can complete update function for me.
However, I think it's only easy when you just show simple format, like
<%# Bind("InsertDate") %>
But, if I want to show 'N/A' when InsertDate is not exist. then how to use <%# Bind %> to achieve the condition check?
I know Bind function supports format string, like
<%# Bind("InsertDate", "0:{dd MMM yyyy}") %>
But it cannot change format base on InsertDate's content.
I even try to use:
<%# FormatString(Bind("InsertDate").ToString()) %>
It seems's not working which normally works for Eval function.
Another example is I have a bitwise column in table (like 5) which is represented by a checkboxlist wrapped by ListView control, like
<asp:checkboxlist>
<asp:ListItem value="1" text="OptionA">
<asp:ListItem value="2" text="OptionB">
<asp:ListItem value="4" text="OptionC">
</asp:checkboxlist>
then how to use <%# Bind %> to achieve two-way bind to bind the bitwise column to this checkboxlist?
Currently what I do is:
set checkboxlist's selected item(value) in ListView's ItemDataBound event handler
using a HiddenField and bind the data to this hiddenfield to
achieve two-way data bind.
In LivtView's ItemUpdating event handler, I update above ListViewUpdateEventArgs' NewValue property to the value I want. and then the EntityDataSource can do the update operation correctly.
But I think this method is not easy and good.
So is there any other better method to do this?
Try to make use of the public data type.
On your code-behind declare your variable as
public string name;
//Do whatever assignment operations to your variable "name"
And on your aspx page. You can call it
<% Response.Write(name); %>

problem assigning declarative values in asp:hyperlink. error: this is not scriptlet. will output as plain text

I am trying to do this:
<asp:HyperLink NavigateUrl='<%= WebContext.RootUrl %><%= WebContext.CurrentUser.UserName %>' runat="server" Text='<%= GetProfileImage(WebContext.CurrentUser.AccountId) %>'></asp:HyperLink>
But am getting the error:
this is not scriptlet. will output as
plain text.
when I mouse over my declarative statements.
Any ideas? Thanks.
You cannot use <%= ... %> literals to set properties of server-side controls.
Instead, you can use a normal (client-side) <a> tag, like this:
<%= GetProfileImage(WebContext.CurrentUser.AccountId) %>
If GetProfileImage doesn't return HTML tags, make sure to escape it.
You can use data binding syntax <%# %>. Just be sure that your hyperlink is either in a databound control, such as a ListView item template, or that you explicitly call DataBind() on the control from code-behind.
You can still populate an <asp:HyperLink> if you provide the ID and runat="server" properties. You can then set any property of the HyperLink from code-behind.
ASP Code:
<asp:HyperLink ID="myLink" runat="server"/>
Code-behind:
public void Page_Init()
{
myLink.NavigateURL = WebContext.RootUrl + WebContext.CurrentUser.UserName;
myLink.Text = GetProfileImage(WebContext.CurrentUser.AccountId);
}
<a href='<%= WebContext.RootUrl %><%= WebContext.CurrentUser.UserName %>'><%= GetProfileImage(WebContext.CurrentUser.AccountId) %></a>

Asp.net, directly assigning properties from value?

Is there a way to express
<% objControl.ObjProp=ObjVar; %>
<my:Control ID="objControl" runat="server" />
As something like this, in one line? And without passing ObjVar as a string?
<my:Control ID="objControl" runat="server" ObjProp=ObjVar />
Unless you're in a databound context, no there's no simple way to do this. If it is a databound context (Like in a repeater/gridview) you can simply go ObjProp='<%# ObjVar %>', but outside that context you can't do it inline unfortunately.
use it like
<my:Control ID="objControl" runat="server" ObjProp="<%# ObjVar %>" />
As fyjham has mentioned, you need to do this in a databound context with the <%# %> syntax. If you are trying to set the property dynamically then your other option is to set it within the server side parent's onload code behind method.
What is ObjVar? If it's a static value, you can just add the attribute tag to the control element like so....
<my:Control ID="objControl" runat="server" MyCustomBooleanProperty="true" />
If it's a member variable of the page containing the control, then I'd do so in the code behind...
protected Page_Init()
{
this.objControl.ObjProp = this.ObjVar;
}
If you're databinding to the control, then the others are correct where you use the databinding context.
<my:Control ID="objControl" runat="server" ObjProp=<%#Eval("ObjVar")%> />

Can I use <%= ... %> to set a control property in ASP.NET?

<asp:TextBox ID="tbName" CssClass="formField" MaxLength="<%=Constants.MaxCharacterLengthOfGameName %>" runat="server"></asp:TextBox>
The code above does not work. I can set the MaxLength property of the textbox in the code behind but i rather not. Is there away I can set the MaxLength property in the front-end code as above?
You could use DataBinding:
<asp:TextBox
ID="tbName"
CssClass="formField"
MaxLength="<%# Constants.MaxCharacterLengthOfGameName %>"
runat="server">
</asp:TextBox>
and in your code behind Page_Load call:
tbName.DataBind();
or directly databind the page:
this.DataBind();
The <%= expression %> syntax is translated into Response.Write(expression), injecting the value of expression into the page's rendered output. Because <%= expression %> is translated into (essentially) a Response.Write these statements cannot be used to set the values of Web control properties. In other words, you cannot have markup like the following:
<asp:Label runat="server" id="CurrentTime" Text="<%= DateTime.Now.ToString() %>" />
Source: https://web.archive.org/web/20210513211719/http://aspnet.4guysfromrolla.com/articles/022509-1.aspx
Try to use custom expression builder:
// from http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx
[ExpressionPrefix("Code")]
public class CodeExpressionBuilder : System.Web.Compilation.ExpressionBuilder
{
public override CodeExpression GetCodeExpression(BoundPropertyEntry entry,
object parsedData, ExpressionBuilderContext context)
{
return new CodeSnippetExpression(entry.Expression);
}
}
And then use it like
<asp:TextBox ID="tbName" CssClass="formField" MaxLength="<%$ Code: Constants.MaxCharacterLengthOfGameName %>" runat="server"></asp:TextBox>
As Ropstah said, it isn't going to work with the <%= expression %> syntax.
But you could probably use databinding, which just requires that you use the <%# expression %> syntax and then call MyTextBox.Databind in CodeBehind.
Of course, at that point it might be more clear to just do the whole operation in CodeBehind.
Another alternative: if you really want this to be declarative, you could get away from the Label and embed your expression in a span tag.That way you still get to apply CSS, etc and I think the <%= expression %> syntax would work.
Why don't you just set it in the Page_Init callback function in the code behind?
This example is geared towards getting the max length from underlying sql types in linq. But you should be able to customise it to your needs
http://blog.binaryocean.com/2008/02/24/TextBoxMaxLengthFromLINQMetaData.aspx
It looks like you want to be able to control the max length of a specific type of text box from a single location so that if that max length needs to change, you only need to change it in one place.
You can accomplish this by using a skin file. You set the max length in the skin file as you would normally and then any textbox that uses that max length would use the skin. If the length changes then you only need to change the skin file.
You can do it with databinding
<asp:TextBox
ID="tbName"
CssClass="formField"
MaxLength='<%# Constants.MaxCharacterLengthOfGameName %>'
runat="server" />
Then in the code behind
protected void Page_Load(object sender, EventArgs e) {
Page.DataBind();
}
You can embed "normal" code in the .aspx file if you so want, like:
<%
tbName.MaxLength = Constants.MaxCharacterLengthOfGameName
%>
<asp:TextBox ID="tbName" CssClass="formField" runat="server"></asp:TextBox>
This harkens back to an older style "classic" ASP way of doing this.

Resources