Reputation: 460
i wrote this piece of code to use TinyMCE (javascript "richtext" editor) on a ASP page. The ASP page itself contains a textbox called "art_content", that generates a ClientID like "ctl00_hold_selectionblock_art_content".
One problem i had was to make a "safe" code that is stored by my aplication, and loaded back to HTML when i goes to the client, then it return to it's "safe" mode before submiting (or postback) to prevent the HTML check error on server side.
My Javascript seems to work properly, but i get the error anyway. It looks like it's not working, although the function is triggering.
Help!
tinymce.init
(
{
selector:'#ctl00_hold_selectionblock_art_content',
plugins:
['table link image textcolor pagebreak code visualblocks charmap'],
toolbar:
'bold,italic,underline'
}
);
function SafeCms(text,encode)
{
if(encode)
{
text=text.replaceAll('<','{{');
text=text.replaceAll('>','}}');
}
else
{
text=text.replaceAll('{{','<');
text=text.replaceAll('}}','>');
}
return text;
}
$(document).ready
(
function()
{
$('#ctl00_hold_selectionblock_art_content').val(SafeCms($('#ctl00_hold_selectionblock_art_content').val(),false));
$("form").submit
(
function()
{
tinymce.triggerSave();
$('#ctl00_hold_selectionblock_art_content').val(SafeCms($('#ctl00_hold_selectionblock_art_content').val(),true));
}
);
}
);
UPDATE: Error presented by server side (page)
A potentially dangerous Request.Form value was detected from the client (ctl00$hold$selectionblock$art_content="<p>ab<em>acac</em>ac...").
CallStack:
[HttpRequestValidationException (0x80004005): Um valor possivelmente perigoso Request.Form foi detectado no cliente (ctl00$hold$selectionblock$art_content="<p>ab<em>acac</em>ac...").]
System.Web.HttpRequest.ValidateString(String s, String valueName, String collectionName) +8818818
System.Web.HttpRequest.ValidateNameValueCollection(NameValueCollection nvc, String collectionName) +111
System.Web.HttpRequest.get_Form() +129
System.Web.HttpRequest.get_HasForm() +8818919
System.Web.UI.Page.GetCollectionBasedOnMethod(Boolean dontReturnNull) +97
System.Web.UI.Page.DeterminePostBackMode() +63
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6785
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +242
System.Web.UI.Page.ProcessRequest() +80
System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +21
System.Web.UI.Page.ProcessRequest(HttpContext context) +49
ASP.content_quality_knownledges_aspx.ProcessRequest(HttpContext context) in c:\Users\Sammuel\AppData\Local\Temp\Temporary ASP.NET Files\root\a3cdd555\dbee70c6\App_Web_e_7yzdu3.2.cs:0
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
Upvotes: 0
Views: 1597
Reputation: 7804
Actually you don't need to manually replace characters, you might always end-up with special cases that you didn't think about and ASP.NET blocks because of security issue.
The best option in my opinion is to encode the content then decode it server side.
I copy my TinyMCE content to an invisible textbox (so user does't end-up seeing an encoded content in his HTML editor)
function encodeContent(copyToId, htmlContent) {
var encodedHtml = encodeURIComponent(htmlContent);
$('#' + copyToId).val(encodedHtml);
}
Then on server side I just get the content of this textbox and decode it
var decodedHtml = HttpUtility.UrlDecode(this.TextBoxNewContent.Text);
I don't know how you initialize your TinyMCE but I personally wrap it in a JS function that I register for calling in the Page_PreRender
method. In real I've many more parameters, here is a simplified code:
protected void Page_PreRender(object sender, EventArgs e)
{
var script = "createHtmlEditor('"
+ this.tinyMceEditor.ClientID + "','"
+ this.TextBoxNewContent.ClientID + "');";
var scriptId = "createHtmlEditor_" + this.tinyMceEditor.ClientID;
ScriptManager.RegisterStartupScript(this, this.GetType(), scriptId, script, true);
}
encodeURIComponent
is a native JavaScript function and HttpUtility
static class is located in System.Web
namespace
NOTE: when I say "invisible" textbox I'm talking about CSS invisible. Because in ASP.NET Visibility="false"
will result of your HTML element not created!
Upvotes: 0
Reputation: 73731
As suggested in this article, you can remove the offending HTML characters from the editor content in the SaveContent
event. If necessary, you can restore them in the BeforeSetContent
event.
For TinyMCE 4, you can use this code:
tinymce.init({
selector: '#ctl00_hold_selectionblock_art_content',
plugins: ['table link image textcolor pagebreak code visualblocks charmap'],
toolbar: 'bold,italic,underline',
setup: function (editor) {
editor.on("SaveContent", function (e) {
e.content = SafeCms(e.content, true);
});
editor.on('BeforeSetContent', function (e) {
e.content = SafeCms(e.content, false);
});
}
});
function SafeCms(text, encode) {
if (encode) {
return text.replace(/</g, '{{').replace(/>/g, '}}');
}
else {
return text.replace(/{{/g, '<').replace(/}}/g, '>');
}
}
I use replace
with a regular expression in SafeCms
instead of replaceAll
(which does not exist by default in Javascript).
Upvotes: 0
Reputation: 4222
I had this problem, in your web.config
Add:
<system.web>
<pages validateRequest="false" />
</system.web>
If you are on .net 4.0 make sure you add this in your web.config
<httpRuntime requestValidationMode="2.0" />
Upvotes: 1