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

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
:)

Related

How to preserve ampersand in URL's querystring when using RegisterClientScriptInclude?

I have the need to add a javascript include to my ASP.NET page. The url of the javascript file has two key/value pairs in the query string. But the ampersand is being escaped and I don't want that.
Page.ClientScript.RegisterClientScriptInclude("myKey",
"https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&s=1")
This results in the following HTML:
<script
src="https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&s=1"
type="text/javascript"></script>
But what I really want is:
<script
src="https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&s=1"
type="text/javascript"></script>
Help?
Actually the encoded ampersand is valid HTML markup. Your goal is an attempt to generate invalid markup. Unencoded ampersands are not valid.
I have run into this in the past and never found a way around it. I needed to create the URL server side and I don't like putting inline code in my aspx pages so I ended up using a Literal control and building the script tag and assigning it.
For your example:
<form id="form1" runat="server">
<asp:Literal ID="ltScriptInclude" runat="server"></asp:Literal>
Then in the Page_Load:
string url = "https://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&s=1";
ltScriptInclude.Text = string.Format(
"<script src=\"{0}\" type=\"text/javascript\"></script>",
url);
A complete recreation would be to also do a check for the registered key by wrapping the assignment in an if like:
if (IsStartupScriptRegistered("myKey"))
{
// assign
// set the key
}
But that is probably not needed since it is not being assigned anywhere else with the change of a PostBack double assigning it.
It's not the cleanest solution and it would have been nice if the RegisterClientScriptInclude had some type of param to tell it to not encode. Unfortunately I don't think there is any way around it and the above isn't too bad. Most includes for script files usually don't have the & so the vast majority would never run into this problem.

Escape double quotes in asp.net Onclick string

I am trying to insert dynamic data into a onclick property for a control the code looks like this
onclick="openRadWindow('<%#Eval("ID";) %>','<%#Eval("ParentObjectID") %>');"
I cant get it to fire and the trouble seems to be the double quotes, what is the correct method on escaping the quotes so that this fires.
You can do use a format string, like this:
onclick='<%# string.Format("openRadWindow(\"{0}, {1}\");", Eval("ID"), Eval("ParentObjectID")) %>'
Is the event just not firing or are you getting any javascript errors as well. Also, I would look at the HTML after the page has been rendered and make sure that the server tags are being processed correctly. There are certain uses that cause them not to actually be processed and will remain <%# Eval("ID") %>.
Thanks to all I was able to get it working correctly using a different method. in the code behind I created a function and in the function I put the following code
Return String.Format("openRadWindow({0},{1});", photo.ID, photo.ParentObjectID)
and in the aspx I added onclick="<%#MyFunction(DirectCast(Container.DataItem,Photo))%>
First thing I see is that semi-colon after "ID" - I think that might be causing your problems.

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');

Explicit localization problem

when trying to translate the confirmation message to Norwegian i get the following error:
Cannot have more than one binding on property 'OnClientClick' on 'System.Web.UI.WebControls.LinkButton'. Ensure that this property is not bound through an implicit expression, for example, using meta:resourcekey.
i use Explicit localization in the following manner:
<asp:LinkButton ID="lnkMarkInvoiced" runat="server" OnClick="lnkMarkInvoiced_OnClick"
OnClientClick="<%# Resources: lnkMarkInvoicedResource.OnClientClick%>"
Visible="False" CssClass="stdtext" meta:resourcekey="lnkMarkInvoicedResource" ></asp:LinkButton>
here's the local resource file entry:
<data name="lnkMarkInvoicedResource.OnClientClick" xml:space="preserve">
<value>return confirm('Er du sikker?');</value>
if i remove the meta attribute i get the English text(default).
how do i get the Norwegian text appearing without resorting to using the code behind?
Update:
removing the meta attribute prevents the exception from occurring but the original problem still exists. I can't get the Norwegian text to show.
only the default English text shows.
Another Update:
I know this question is getting old but i still can't get the Norwegian text to display.
If anyone has some tips please post a response.
Looks like you're making the problem harder by inlining the onclick. Why not split it out to a separate line?
<script>
function markInvoiced()
{
return confirm('<%= Resources.SomehowGet.lnkMarkInvoicedResource.OnClientClick%>');
}
</script>
<asp:LinkButton ID="lnkMarkInvoiced" runat="server" OnClick="lnkMarkInvoiced_OnClick"
OnClientClick="return markInvoiced();"
Visible="False" CssClass="stdtext" meta:resourcekey="lnkMarkInvoicedResource" ></asp:LinkButton>
And while we're looking at your code, you realize that you're essentially building an <a> tag, right? As such, why not just build an <a> and save yourself some grief?
And finally, next project why not ditch the built-in ASP.NET localization nighmare in favor of something sane like FairlyLocal, in which case you'd write this:
<a href="#" onclick="return confirm(<%=_"really?"%>) onserverclick="lnkMarkInvoiced_OnClick" runat="server">
<%=_("Mark Invoice")%>
</a>
Are you using the .NET resource manager and satellite assemblies to store your localized resources? It looks like you have hard-coded the alternative language in your markup, rather than storing it in a language-specific resources assembly...
.NET has some extremely rich localization and globalization capabilities. If you use them properly, localization should be a pretty automatic thing (assuming your client is providing their language code as part of the HTTP headers). Even if your client has not configured their browser with the appropriate language, it is still easy enough to manually change the UI culture via a user request (clicking a flag icon, configuring a setting, etc.)
This article might be helpful: ASP.NET Web Page Resources Overview
That meta tag is using implicit localization when you're using explicit localization in the OnClientClick. You will need to choose one method or the other. If you are to use explicit localization, you'll need to do the necessary work to set the proper culture info in your application in the code-behind.

Label Text Property and entities

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>.

Resources