Ian Ian - 1 month ago 14x
ASP.NET (C#) Question

AllowHtml works on Create but not on Edit ASP.Net MVC 5

This is an


I have a simple model whose one of its properties allows a

public class FooModel {
//other properties

public string BarField { get; set; }

And a controller which uses the model as shown below:

[OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]
public class FooController : Controller {
//some other codes...

// GET: Foo/Create
public ActionResult Create(int? id, int number = 0) {
//some code

// POST: Foo/Create
public ActionResult Create(FooModel fooModel) {
//some code

// GET: Foo/Edit/5
public ActionResult Edit(int? id, int number = 0) {
//some code

// POST: Foo/Edit/5
public ActionResult Edit(FooModel model, FormCollection collection) {
//some code

Upon reading some of the posts in SO:

  1. AllowHtml attribute not working

  2. AllowHtml attribute doesn't work

  3. AllowHtml not working

I know that the following must be done to ensure the
attribute to work:

  1. use
    <httpRuntime requestValidationMode="2.0" />
    in the web.config

  2. clear up cache of the controller where the model is passed and used
    [OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]

Thus, I have the following complete element for my
in the web.config:

<authentication mode="None" />
<compilation debug="true" targetFramework="4.6" />
<httpRuntime targetFramework="4.5" requestValidationMode="2.0" />
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />

And, as you can see, I also have put the
attribute on top of the controller:

[OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]

Now, this works very well for
Action (that is, I can insert HTML element in the
and the post is accepted and the Action is called without problem).

But when I do the
Action, the action is not even called and the error:

A potentially dangerous Request.Form value was detected from the client ( BarField="...words here <i>and also here</i><...").

Description: ASP.NET has detected data in the request that is potentially dangerous because it might include HTML markup or script. The data might represent an attempt to compromise the security of your application, such as a cross-site scripting attack. If this type of input is appropriate in your application, you can include code in a web page to explicitly allow it. For more information, see http://go.microsoft.com/fwlink/?LinkID=212874.

is shown on the page. Why is this so?


The exception is thrown because you have included an additional parameter FormCollection collection in the Edit() method.

When you apply the [AllowHtml] attribute, its sets the RequestValidationEnabled property of the properties ModelMetadata to false. During the model binding process, the DefaultModelBinder checks this value and because its false, no exception is throw when binding to your model.

However, FormCollection is just a NameValueCollection and is populated by reading the Request.Form values. There is no model and associated metadata, so the exception is thrown. Exactly the same would happen if you were to use

var barField= Request["BarField"];

although using the Unvalidated property of Request will work

var barField = Request.Unvalidated.Form["BarField"];

You could also make it work by applying the [ValidateInput(false)] attribute to the method but that will apply to the whole model and is the least secure way to disable request validation.

Removing the FormCollection collection parameter in the Edit() method will solve the problem, and in any case, there is really no reason to ever use FormCollection in MVC (you should always bind to a model).