2

I am writing an MVC3 site, which uses tinymce as a WYSIWYG text editor. I save that text via an AJAX call using jQuery. I've found the query is not sent, if my data includes HTML, so I need to do this:

 var postData = {
                  couponId: couponId,
                  coupon: escape(coupon),
                  imagePath: image,
                  imageAlignment: imageAlignment
                };

             $.post('@(Url.Action("SaveCoupon"))', postData, function (data) {

in order to get my data passed through to the server. This turns

<p>this is a test</p>

in to

%3Cp%3Ethis%20is%20a%20test%3C/p%3E

I've been trying to work out how to convert it back. The HtmlString, HtmlHelper and HttpUtility classes just return it verbatim, I thought HttpUtility.HtmlDecode was what I needed for sure, but it just plain does not do what I need. I need to store this as decoded HTML in my database, so I can't just re-encode it on the client side ( although I am concerned that I won't be able to send it back using AJAX either, I've not even got that far, yet ). What's the best way to transmit HTML through an AJAX call, store it in the form it was entered, and return it back to the client for display ?

2
  • Seems I can't provide an answer to my own question for 8 hours. The answer is HttpUtility.UrlDecode Commented Dec 12, 2011 at 1:14
  • Why is it better then Html.Raw() ? Commented Dec 12, 2011 at 1:41

4 Answers 4

2

I've found the query is not sent, if my data includes HTML

No, you found wrong. The query is sent but the server rejects it because it contains dangerous characters. Basically it throws an exception before it reaches your controller action. In ASP.NET MVC 3 there are a couple of possibilities to avoid this.

The first one is to decorate your view model property that will receive the HTML with the [AllowHtml] attribute (recommended):

public class CouponViewModel
{
    public int CouponId { get; set; }
    [AllowHtml]
    public string Coupon { get; set; }
    public string ImagePath { get; set; }
    public string ImageAlignementh { get; set; }
}

which is what your controller action will take as parameter:

[HttpPost]
public ActionResult SaveCoupon(CouponViewModel model)
{
    ...
}

Now when sending your AJAX request don't do any escaping or stuff. jQuery will take care of properly url encoding your parameters:

var postData = {
    couponId: couponId,
    coupon: coupon,
    imagePath: image,
    imageAlignment: imageAlignment
};

$.post('@Url.Action("SaveCoupon")', postData, function (data) {
    ...
});

Another possibility is to decorate the entire action with the [ValidateInput] attribute which will disable request verification for the entire request (not recommended):

[HttpPost]
[ValidateInput(false)]
public ActionResult SaveCoupon(CouponViewModel model)
{
    ...
}
Sign up to request clarification or add additional context in comments.

Comments

1

I'm not sure entirely why HtmlDecode isn't doing what you need but I do have an alternate approach. You can allow the html data to be posted by putting the following attribute on your controller

[ValidateInput(false)]

In .Net 4 you may also need

<httpRuntime requestValidationMode="2.0" /> 

in your web.config

Of course you will need to deal with the possibility of malicious input on your own.


One other possibility I wanted to check - how are you outputting your html? In razor you'll need to use @Html.Raw(mystring) otherwise your string will be automatically escaped again.

1 Comment

"In .net 4 you may also need in your web.config" need what?!
1

I have seen a similar issue with the razor engine in webmatrix. The post seems to hang because the request action causes the "potentially dangerous content error".

My partial solution is to use Request.Unvalidated().Form["form_name"] to retrieve the string which includes the tinymce form data.

I then reencode and store it in my database. Unfortunately the razor engine uses a different encoding than JQuery so I can't unencode it for my Ajax panels yet.

Comments

0

If you don't want your text to be encoded you can use the Raw extension method;

@Html.Raw("<p>this is a test</p>");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.