Using duplicate asp.net control IDs in different conditional blocks / validators - asp.net

I have an asp page that renders controls based on a Request parameter. Simplified example:
<% if (Request.QueryString["personType"] == "D") { %>
<asp:TextBox ID="TextBoxName" runat="server" Text='<%# Bind("first_name") %>' />
<asp:TextBox ID="TextBoxSurname" runat="server" Text='<%# Bind("surname") %>' />
<% } else { %>
<asp:TextBox ID="TextBoxName" runat="server" Text='<%# Bind("first_name") %>' />
<% } %>
<asp:RequiredFieldValidator ID="RequiredFieldValidator" runat="server"
ControlToValidate="TextBoxName" ErrorMessage="Please enter an name." />
However, the compiler and runtime are complaining that the TextBoxName is not a unque ID. But surely it is, if the output is conditional and exclusive?
I could rename them TextBoxNameA (if block) and TextBoxNameB (else block), but the odd thing is that the validator still seems to fire on TextBoxNameB, even if the validator is inside the else block and the code runs through the first block at runtime
How can I set the page to render one or the other boxes, without conflicting IDs and conflicting Validators?
Thanks for any help
Ryan

How about moving around your logic?
<asp:TextBox ID="TextBoxName" runat="server" Text='<%# Bind("first_name") %>' />
<% if (Request.QueryString["personType"] == "D") { %>
<asp:TextBox ID="TextBoxSurname" runat="server" Text='<%# Bind("surname") %>' />
<% } %>
<asp:RequiredFieldValidator ID="RequiredFieldValidator" runat="server"
ControlToValidate="TextBoxName" ErrorMessage="Please enter an name." />

But server side, how is the parser supposed to distinguish the two?
And while parsing it will not be able to determine that one should be displayed and one shouldn't.
You need to give each server side control a different ID, regardless of it being displayed to the client.
You can restructure you code like this, as TextBoxName will always display (and with the same text):
<asp:TextBox ID="TextBoxName" runat="server" Text='<%# Bind("first_name") %>' />
<% if (Request.QueryString["personType"] == "D") { %>
<asp:TextBox ID="TextBoxSurname" runat="server" Text='<%# Bind("surname") %>' />
<% } %>
And no more problem.

Since the Name textbox will show up regardless of the condition, you can just take that out of your if block all together and then just conditionally show the SurName textbox and that should solve your problem.

Related

Servertag format wrong

I'm using a gridview where I try to set the visibility for 2 buttons and a label and also the text of the label via commands in the aspx file itself.
Now I've run into the problem that regardless if I use <%# or <%= or <% I always get "servertag format wrong".
Code:
<asp:TemplateField HeaderText="Status" SortExpression="Status">
<ItemTemplate>
<asp:Button runat="server" text="Freigeben" Visible="<%#!IsEnvelopeCleared((String)Eval("Status")) %>"/>
<asp:Button runat="server" text="Ablehnen" Visible="<%#!IsEnvelopeCleared((String)Eval("Status")) %>"/>
<asp:Label runat="server" text="<%# Bind("Status") %>" Visible="<%# IsEnvelopeCleared((String)Eval("Status")) %>"/>
The error appears on the first <%# already (I also tried removing the ! to no avail).
Overall double quote is the problem.
You have to use single quote. Following is one of the line from your code.
<asp:Button runat="server" text="Freigeben" Visible='<%#!IsEnvelopeCleared((String)Eval("Status")) %>'/>

Required Field Validator hidden in asp.net Repeater

I have reapeater in my code and trying to validate the textbox using asp.net required field validator. But validation messsage
not displaying, i opened the developer tools and found that style="visibility:hidden" added into the required field validator.
Below is my code
<asp:Repeater ID="RepeaterCategory" runat="server" DataSource='<%# this.Categories.Count==0 ? null : this.Categories %>'>
<ItemTemplate>
<div>
<asp:Label runat="server" Visible="true" Text="Category" />
<asp:PlaceHolder runat="server" Visible="true">
<asp:TextBox ID="txtCategoryID" runat="server" value="1" />
<asp:TextBox ID="txtCategoryName" runat="server" value="<%# (Container.DataItem as Category).Name %>" />
<asp:RequiredFieldValidator runat="server" ErrorMessage="<br/>This is a required field" ControlToValidate="txtCategoryName" ValidationGroup="NewCategoryGroup"></asp:RequiredFieldValidator>
</asp:PlaceHolder>
<asp:LinkButton runat="server" ToolTip="Save" ValidationGroup="NewCategoryGroup" OnClick="SaveCategory_Click"><img src='<%# some path%>/images/save.gif' /></asp:LinkButton>
<asp:LinkButton runat="server" ToolTip="Close" OnClick="CloseCategory_Click"></asp:LinkButton>
</div>
</ItemTemplate>
</asp:Repeater>
Code behind file
protected void SaveCategory_Click(object o, EventArgs e)
{
Page.Validate("NewCategoryGroup");
if (!Page.IsValid)
return;
//logic
}
Can anyone suggest how to enable it?
The style="visibility:hidden" is default behavior. It changes to style="visibility: visible;" when the error message needs displaying. Therefore you probably don't have an error.
The validator is a 'RequiredFieldValidator', and since the textbox that is being validated is already filled with the value "TestCategory" there are no errors. If you just add text to the Save button (which has no ID tag) so that it becomes visible, remove the value from the txtCategoryName textbox and click the save button you will see the error message.
This works:
<asp:TextBox ID="txtCategoryName" runat="server" value="" />
<asp:RequiredFieldValidator runat="server" ErrorMessage="<br/>This is a required field" ControlToValidate="txtCategoryName" ValidationGroup="NewCategoryGroup"></asp:RequiredFieldValidator>
<asp:LinkButton runat="server" ToolTip="Save" ValidationGroup="NewCategoryGroup" OnClick="SaveCategory_Click" ID="LinkButton1">Save Me!</asp:LinkButton>
You don't need this code
Page.Validate("NewCategoryGroup");
if (!Page.IsValid)
Another advantage is that the validators work now without a postback, this saves a roundtrip to the server.
And ALWAYS do server side validation also, but try to do the first validation without postback.
UPDATE
What you want is probably validation per item. And since your validationgroup is always the same it will fire for all textboxes. Try this:
<asp:Repeater ID="RepeaterCategory" runat="server">
<ItemTemplate>
<div>
<asp:TextBox ID="txtCategoryName" runat="server" ValidationGroup='<%# "myVal_" + Container.ItemIndex %>' Text='<%# Eval("Category") %>' />
<br />
<asp:RequiredFieldValidator runat="server" Display="Dynamic" ErrorMessage="This is a required field<br />" ControlToValidate="txtCategoryName" ValidationGroup='<%# "myVal_" + Container.ItemIndex %>'></asp:RequiredFieldValidator>
<asp:LinkButton runat="server" ValidationGroup='<%# "myVal_" + Container.ItemIndex %>' OnClick="Button1_Click" ID="LinkButton1">Save Me!</asp:LinkButton>
</div>
</ItemTemplate>
</asp:Repeater>

Replace in ASP.net

i'm new to asp.net and i'm struggling with the replace function that i'm hoping someone can help with. When i use some test text it works fine (as in the example below) but as soon as i replace the test text with the value from the database (Eval("PContent")) i get a databinding error. The label separately works fine.
Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
I've tried al-sorts but i cannot get around this.
Here's my code:
<asp:Label runat="server" ID="Label4" text='<%# Eval("PContent") %>' />
<%
Dim text1 As String = "Some text here [q]testing[/q]"
Dim output As String = text1.Replace("[q]", "<span class='quote'>")
Dim VS As String = output.Replace("[/q]", "</span>")
Response.Write(VS)
%>
Thanks for your time - sorry if this is a very n00b thing to ask! I did try search for an answer on here and google but i can't find anything...
**Update....
<asp:ListView ID="ListView1" runat="server" DataSourceID="SqlDataSource1">
<ItemTemplate>
<asp:Label runat="server" ID="Label5" text='<%# Eval("PMonthName")%>' />
<asp:Label runat="server" ID="Label6" text='<%# Eval("PDay")%>' /></small>
</div><!--middlebartext -->
<div class="middlebartexttitle"><a href="/Details.aspx?ID=<%# Eval("BID")%>">
<asp:Label runat="server" ID="Label3" text='<%# Eval("Header")%>' /></a><br />
<asp:Label runat="server" ID="Label4" text='<%# Eval("PContent")%>' />
Permalink
<div class="ruler"></div>
</ItemTemplate>
</asp:ListView>
<asp:SqlDataSource
ConnectionString="<%$ ConnectionStrings:Conn2 %>"
ID="SqlDataSource1" runat="server"
SelectCommand="SELECT * from tablename where Deleted = 'False' Order By DateAdded DESC"
onselected="SqlDataSource1_Selected">
</asp:SqlDataSource>
I've cut a chunk of code out so it's not as long :)
It's another way to do the replace more short:
C#
<%# ((string)Eval("PContent")).Replace("[/q]", "</span>") %>
VB.net
<%# (Eval("PContent").ToString().Replace("[/q]", "</span>") %>
I don't know a lot Vb.net but I think the code above works.
I hope that help you.
I don't see PContent defined in your question, but
it would be simpler to do something like,
Label4.Text = [value from db]
You could set the text after you have fetched the records from database
Try changing this:
<div class="middlebartexttitle"><a href="/Details.aspx?ID=<%# Eval("BID")%>">
<asp:Label runat="server" ID="Label3" text='<%# Eval("Header")%>' /></a><br />
<asp:Label runat="server" ID="Label4" text='<%# Eval("PContent")%>' />
Permalink
To:
<div class="middlebartexttitle"><a href='/Details.aspx?ID=<%# Eval("BID")%>'>
<asp:Label runat="server" ID="Label3" text='<%# Eval("Header")%>' /></a><br />
<asp:Label runat="server" ID="Label4" text='<%# Eval("PContent")%>' />
<a href='/Details.aspx?ID=<%# Eval("BID")%>'>Permalink</a>
Since Eval requires quotes for the field it's evaluating, my guess is that the quotes you have defining the href attributes are throwing it off. Change those to single quotes (like you have everywhere else) and see if that works.
Also, you can learn more about inline expressions (and when to use them) at http://support.microsoft.com/kb/976112

conditional markup in control's template

I have a repeater control on my .aspx page. There are times where a product is unique, so you can't change it's quantity, but in other cases when there are lots of items of this product, you should be able to edit it's quantity using a textbox and a linkbutton. Both OnlyOne and Quantity are present in the binded collection classes. I need to check the OnlyOne condition, something like that:
<% if (OnlyOne) { %>
<%# Eval("Quantity") %>
<%} else { %>
<asp:TextBox ID="TextBox1" runat="server" />
<asp:LinkButton ID="LinkButton1" runat="server">OK</asp:LinkButton>
<% }%>
The problem is that ASP.NET doesn't find the OnlyOne field. I've tried also (bool)Eval("OnlyOne"), but that didn't work also. So how should I write the condition?
Done it like that:
<asp:Label Text='<%# Eval("Quantity") %>' runat="server" ID="QuantityLabel" Visible='<%# Eval("OnlyOne") %>' />
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("Quantity") %>' Visible='<%# !(bool)Eval("OnlyOne") %>' />
<asp:LinkButton ID="LinkButton1" runat="server" Visible='<%# !(bool)Eval("OnlyOne") %>' Text="OK" />
But I am still interested to hear the answer :) .

Why <%= %> works in one situation but not in another

This is stemming from a bad answer I gave last night. The curiosity as to why one method works and not the other is bugging me and I'm hoping someone smarter than me can give me the proper explanation (or point me to the documentation) of why the following behavior is as it is.
Given the following code-behind:
protected string GetMyText(string input)
{
return "Hello " + HttpUtility.HtmlEncode(input);
}
Why does this work
<asp:Label ID="Label1" runat="server"><%= GetMyText("LabelText") %></asp:Label>
but this does not
<asp:Label ID="Label1" runat="server" Text='<%= GetMyText("LabelText") %>' />
Edit - added
At the risk of having my original dumb answer downvoted more times, here's the link to the original question, since some of the answers I'm getting now were already covered in that question.
Why can't I set the asp:Label Text property by calling a method in the aspx file?
Using <%= %> is equal to putting Response.Write("") in your page. When doing this:
<asp:Label ID="Label1" runat="server"><%= GetMyText("LabelText") %></asp:Label>
The ASP.NET processor evaluates the control, then when rendering, it outputs the control's contents & calls Response.Write where it sees <%=.
In this example:
<asp:Label ID="Label1" runat="server" Text='<%= GetMyText("LabelText") %>' />
You can't use Response.Write("") on a Text attribute because it does not return a string. It writes its output to the response buffer and returns void.
If you want to use the server tag syntax in ASP.NET markup you need to use <%# %>. This combination of markup data binds the value in the tags. To make this work, you'll then need to call DataBind() in your page's Load() method for it to work.
Because they are both server side instructions - the second piece of code is equivalent to:
<asp:Label ID="Label1" runat="server" Text='Response.Write(GetMyText("LabelText"))' />
<%= GetMyText("LabelText") %> basically means
Response.Write(GetMyText("LabelText"));
Here it is OK.
<%= GetMyText("LabelText") %>
However when you use this:
<asp:Label ID="Label1" runat="server" Text='<%= GetMyText("LabelText") %>' />
It basically means:
Label1.Text = Response.Write(GetMyText("LabelText"));
which is a wrong statement.
Wrong format:
<asp:Label ID="Label1" runat="server" Text='<%= GetMyText("LabelText") %>' />
Right format with using resources:
<asp:Label ID="Label1" runat="server" Text='<%$ Resources:Resource, MyText %' />
For it to work in the second case, you'd want it as follows:
<asp:Label ID="Label1" runat="server" Text="<%# GetMyText("LabelText") %>" />
And then Label1 will need to be databound.
Do this on server controls, if you have your LabelText in a Global Resource file:
<asp:Label ID="Label1" runat="server" Text="<%$ Resources: resourceName, LabelText %>" />

Resources