Vincent
Vincent

Reputation: 742

ASP.NET MVC AllowHtml bug or something I didn't use correctly

My model contains a string field called "longdescription" which gets the value of the tinymce editor's content

Public class ArticleModel:BaseModel{
            [StringLength(8000, ErrorMessage = "Long description must be in 8000 characters or less"), AllowHtml]
    public string LongDescription { get; set; }
}

Here is my controller code

[HttpPost]
public ActionResult AddEdit(ArticleModel model)
{
    string buttonName = Request.Form["Button"];
    if (buttonName == "Cancel")
        return RedirectToAction("Index");

    // something failed
    if (!ModelState.IsValid)
    {

     }

    // Update the articles
  }

My problem is when I use Request.Form to access the post value, it's working fine without throwing "A potentially dangerous...." error, but when I use Request.Params["Button"], it threw that errors. Is something I am missing?

Thanks

Updated

Sorry the answer Adam gave doesn't really answer my question. Can anyone give more suggestion?

Upvotes: 1

Views: 490

Answers (2)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

It is the HttpRequest.Params getter that is throwing this exception. This getter basically builds and returns a key/value pair collection which is the aggregation of the QueryString, Form, Cookies and ServerVariables collections in that order. Now what is important is that when you use this getter it will always perform request validation and this no matter whether you used the [AllowHtml] attribute on some model property or if you decorated the controller action with the [ValidateInput(false)] attribute and disabled all input validation.

So this is not really a bug in the AllowHtml attribute. It is how the Params property is designed.

As @Adam mentioned in his answer you should avoid accessing request values manually. You should use value providers which take into account things such as disabled request validation for some fields.

So simply add another property to your view model:

public class ArticleModel: BaseModel
{
    [StringLength(8000, ErrorMessage = "Long description must be in 8000 characters or less")]
    [AllowHtml]
    public string LongDescription { get; set; }

    public string Button { get; set; }
}

and then in your controller action:

[HttpPost]
public ActionResult AddEdit(ArticleModel model)
{
    string buttonName = model.Button;
    if (buttonName == "Cancel")
    {
        return RedirectToAction("Index");
    }

    // something failed
    if (!ModelState.IsValid)
    {

    }

    // Update the articles
}

Upvotes: 1

Adam Tuliper
Adam Tuliper

Reputation: 30142

Ideally you shouldn't really be using either. Those are more Web Forms centric values even though they 'can' be used.

Either pass in a FormsCollection item and check it there using collection["Button"] or even better - your cancel button itself should probably just do the redirect. Why post when you do nothing but redirect?

In your view you can emit the url via Url.Action() and put that into your button's click handler (client side)

Upvotes: 2

Related Questions