Label Text Property and entities - asp.net

The following asp label fails to be displayed in the browser, can someone please
tell me what I am doing wrong. I expect to see the value <abc> but instead
I get nothing.
<asp:Label ID="Label1" runat="server" Text="<abc>"></asp:Label>
By the way, I realize that I can accomplish the same thing doing the following:
<asp:label id="Message1" runat="server"> <abc> </asp:Label>
But that is not really what I am asking for, what I would like to know is if using a string such as "<abc>" in an attribute value for an asp elements is allowed or not. In other words, is this an ASP.Net bug or is this behavior by design and if it’s by design what’s the reason for such design?
Thank you very much.

Believe it or not, but you can include entities without escaping them, thus:
<asp:Label runat="server" ID="myLabel" Text="<abc>" />
This will render an <abc> tag.
Edit: OK, sorry, you want to display the brackets, not make a tag, of course..
Using entity references in the Text attribute will give the same result - an (invisible) <abc> tag - because they are translated when the tag is parsed server-side. What you must do is:
<asp:Label runat="server" ID="myLabel" Text="&lt;abc&gt;" />
This will give the desired result - the & entity reference will render an ampersand to the client. Followed by lt;, the result is a correct client-side entity reference (<). Which will render as <.
To answer you questions explicitly: Yes, using entity references in ASP.NET attributes is (obviously) OK, since it's an XML format. This is not really a 'decision' on Microsoft's part (and certainly not a bug) - i's simply XML.
The trick is realizing when the entity references are parsed (when the tag is parsed on the server), and what the resulting text is, which is what will be sent to the client.

Yes it's allowed of course. Label control's purpose is to show text and markup to client. And it's really useful I think. injected code is your responsibility.

The asp.net aspx parser will unescape the "<" and ">" to "<" and ">". It will generate something like this method:
[DebuggerNonUserCode]
private Label __BuildControlLabel1()
{
Label __ctrl = new Label();
base.Label1 = __ctrl;
__ctrl.ApplyStyleSheetSkin(this);
__ctrl.ID = "Label1";
__ctrl.Text = "<abc>";
return __ctrl;
}
If you wanted to write it in the text property you could double escape like "&lt;", but it is probably easier just to write it between start and end tags like you mention.
<asp:Label ...><abc></asp:Label>.

Related

ASP.NET tags don't expand in OnClientClick

I have the following two buttons:
<asp:Button ID="btnVote" runat="server" Text="Vote!" PostBackUrl="<%$RouteUrl:id=2, routename=Results%>"/><br />
<asp:Button ID="btnResults" runat="server" Text="Results ->" OnClientClick="location.href='<%$RouteUrl:id=2, routename=Results%>'"/>
The first <%$ %> expands as intended, while the second (identical!) one gets used as typed ( = not expanded). I am very new to ASP.NET, coming from PHP, and this is from my learning/test site.
What am I doing wrong and how can I fix it?
The ASP.NET expression syntax (<%$ ... %>) can only be used to directly assign values to properties of server controls. I think the problem you're having is that the expression syntax is embedded within a string, and not directly bound to the "OnClientClick" attribute.
Trying changing your second button to
<asp:Button ID="btnResults" runat="server" Text="Results ->" OnClientClick="<%$RouteUrl:id=2, routename=Results%>" />
If that works, you may need to modify your expression to return that extra text you need. Or, create another route that returns said info (the current value wrapped in the "location.href" attribute).
You can find more information about these expressions here: ASP.NET Expressions Overview.

Why does databound property of ASP.NET usercontrol work only without quotes?

I have a custom ASP.NET user control implemented fully in code-behind. The control has one string property and its declarative markup looks like this:
<uc:MyControl ImageUrl="/Content/images/" runat="server" />
Most likely the actual declaration will use data binding syntax like this:
<uc:MyControl ImageUrl="<%# PageInfo.ImageUrl %>" runat="server" />
Now here's the odd part pertaining to my question. If I use the above syntax, the data binding does not work and the value of ImageUrl at run-time is the string literal of whatever is between quotes. However, if I remove the double quotes, it works as expected:
<uc:MyControl ImageUrl=<%# PageInfo.ImageUrl %> runat="server" />
The same behavior occurs with both double and single quotes. I am puzzled by this and although the code is working it's really not optimal as putting values in quotes is the norm and the approach to make the data binding work is decidedly unorthodox.
Anyone have any ideas on why this only works without quotes?
I found the problem...it was something to do with the file (probably encoding, but not sure). On a whim, I copied the code to a new file and deleted the original. Now the data binding works with the quotes as it should.

Globalization difference in inline tags in ASP.NET

Is there any advantage/downfalls between using the inline write tag instead of the resource tag? Example:
<%=Resources.Site.SampleString %>
The resources tag (expression tag) as seen in any MSDN example:
<asp:Literal id="Literal1" runat="server" text="<%$ Resources:Site, SampleString %>" />
I find the first option far easier to use, and it has IntelliSense, but maybe it won't function the same?
These methods will function exactly the same. The latter simply calls first one; there is a reason why strongly-typed resources access code is being generated in the background. Therefore you can use whatever method you please.
By the way, there is also another way - by using meta:resourcekey attribute. So you should be able to write:
<asp:Literal id="Literal1" runat="server"
meta:resourcekey="SampleString" text="Default one" />
and it all should work exactly the same.
EDIT on implicit Localization.
What I forgot to mention, is that with meta:resourcekey certain conditions have to be met. The conditions are:
Values are taken from App_LocalResources, therefore related resource file need to exist
Related resource file name must be pagename.resx, for example: Default.aspx.resx, Default.aspx.es.resx
The resource file must contain keys in form of resourcekey.propertyname, for example SampleString.Text, SampleString.ID (although I wouldn't localize control ID's)
Because of how resources are generated, the key mentioned above must exist in invariant resource file (Default.aspx.resx), or it won't be localized.
I realised after some time that the <%=Resources.Site.SampleString %> method does not have designer support (which is understandable). This doesn't bother me, but it is a difference (for future readers).
So if you need or want designer support, the second option would be necessary.

CKEditor breaking custom .NET tags by converting single quotes to double quotes

At the client's request, we just upgraded a custom CMS system for a large site from FCKEditor 2.x to CKEditor 3.5.3.
Inside an ItemTemplate I have a custom UserControl tag in which the attributes are populated by DataBinding, like so:
<my:Viewer runat="server">
<ItemTemplate>
<my:CustomTag runat="server"
ImageUrl='<%# DataBinder.Eval(Container.DataItem, "ImageUrl") %>' />
</ItemTemplate>
</my:Viewer>
So, the point is that the above works just fine. However, when the HTML is put into the latest CKEditor, CKEditor changes the ImageUrl attribute to use double-quotes instead of single quotes. Once it's changed to double quotes, it causes a parsing error on the .aspx page. Changing: "ImageUrl" to "ImageUrl" works, but it's not ideal for our client who is going to have to update every page that exists in a very large CMS system. So, I'm asking this question hoping someone might know of a way to toggle CKEditor to use single quotes in HTML attributes by default instead of double quotes to reduce the amount of work my client is going to have to do.
I'm only looking for easy configuration-type changes, not patching the editor, etc.
This should do what you want
Taken from here
http://cksource.com/forums/viewtopic.php?f=11&t=20647&sid=f47526ecfb1f2303ad0b923ceed7aafe&start=10
To avoid CKEditor changing special chars:
switching in source view:
CKEDITOR.instances.TEXT.on( 'mode', function(ev) {
if ( ev.editor.mode == 'source' ) {
var str=ev.editor.getData();
str=str.replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, "\"");
ev.editor.textarea.setValue(str);
}
});
When save edited document:
var html=CKEDITOR.instances.TEXT.getData()
html=html.replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, "\"");
I'm going to say that the " solution that I mentioned being too much work is simply the only answer...just to put some closure on this. Or, if I can find a way, I'll withdraw the question. Thanks rqmedes for trying...I'd actually forgotten all about this question until I got your response
:)

Why does ASP.Net rewrite relative paths for runat=server anchor controls?

I have my UserControls in a ~/Controls folder in my solution:
/Controls/TheControl.ascx
If specify the following:
<a id="theId" runat="server" href="./?pg=1">link text</a>
ASP.Net seems to want to rewrite the path to point to the absolute location. For example, If the control is on site.com/products/fish/cans.aspx the link href will be rewritten to read
<a id="munged_theId" href="../../Controls/?pg=1>link text</a>
Why does Asp.Net rewrite these control paths, and is there an elegant way to fix it?
I just want the anchor control to spit out exactly what I tell it to!!! Is that so hard?
EDIT:
I've basically done what Kelsey suggested. I knew I could do it this way, but I don't like adding markup in my code when I want something relatively simple. At least it solves the problem:
Aspx page:
<asp:PlaceHolder ID="ph" runat="server"></asp:PlaceHolder>
Code-behind:
var anchor = new HtmlGenericControl("a") { InnerText = "Previous" + " " + PageSize) };
anchor.Attributes["href"] = "?pg=" + (CurrentPage - 1);
anchor.Attributes["class"] = "prev button";
ph.Controls.Clear();
ph.Controls.Add(anchor);
As you can see by the amount of code needed for what is essentially supposed to be be a simple and light-weight anchor, it's not the most optimal solution. I know I could use a Literal but I figured this was cleaner as I'm adding more than one anchor.
I would be interesting in knowing WHY ASP.Net takes over and tries to fix my URL, though.
Why do you have runat="server" and no ID defined? Do you need to access it server side? If you remove the runat="server" everything will work as expected.
For more information regardinging how ASP.NET handles paths check out this MSDN article.
Edit: You can get around the problem then by using a Literal control and then outputing the raw <a href... to it.
Eg:
<asp:Literal ID="myLiteral" runat="server" />
myLiteral.Text = "link text";
Then you can set the visible property on the Literal however you want.
I know this is a bit of an old topic, but I was running into this problem as well and in the end went with a similar solution, but was able to save a few lines of code by doing this in the ascx:
<anchor id="myAnchor" runat="server" href="xxx">link text</anchor>
Then in the code behind, I referenced it using an HtmlGenericControl and can then do this:
myAnchor.TagName = "a";
// other properties set as needed
Anyway, I thought I'd post in case anyone else stumbles in here with the same issue.
Best bet is to make everything app root relative using the magic ~/ lead-in to the url. That tends to keep stuff straight.
There isn't a great answer to your question. ASP.NET is going to treat a relative path in a UserControl as relative to the path of the user control.
What you can do is in the code behind for your user control, set the HRef property of your anchor tag based on the Request.Path property. Then you can create URLs relative to the page.
Alternative is to use a literal like Kelsey was suggestion, or I would just try and map everything app relative with ~/ like Wyatt suggested.
Even a literal doesn't work using ICallBackEventHandler and RenderControl at least... I ended up hacking the tag back client-side :/ e.g in JQuery:
$('#munged_theId').attr('href', './?pg=1');

Resources