How to make AllowHtml work when the model is in a collection

I’m using ASP.NET MVC 4. I have a model that has more than ten properties; but only two properties have AllowHtml attributes. I just want these two properties to by-pass request validation check. I will sanitize them myself. But I want other properties to
be validated.

When I use this model one by one, I mean createupdate a single one then AllowHtml works. But there is a case where I have to make a batch update. In this case I bind a generic List<> object of this model. Unfortunately AllowHtml is ignored in this case.

I tried to figure out what was going on by adding a custom ModelBinder for the generic List object but I wasn’t successfull.

Does anyone have an idea on how to bind collections by also honoring the AllowHtml attribute on the model?

Thanks in advance

Hi kpaxco,

Base on my test in a MVC 4 project, it works fine.

Please create a new project and try again to check whether you could reproduce that issue.

This is my code below:

public class StudentInfo
    {
        public string Name{get;set;}
        [AllowHtml]
        public string Description{get;set;}
    }
  public ActionResult AllowHtmlTest()
        {
        List<StudentInfo> ss=new List<StudentInfo>();
            for(int i=0;i<3;i++)
            {
                StudentInfo s=new StudentInfo(){ Name="name"+i};
                ss.Add(s);
            }
            return View(ss);
        }
        [HttpPost]
        public ActionResult AllowHtmlTest(List<StudentInfo> ss)
        {
            return View(ss);
        }
@model List<MvcDemo2.Models.StudentInfo>

@{
    ViewBag.Title = "AllowHtmlTest";
}

<h2>AllowHtmlTest</h2>

<fieldset>
    <legend>StudentInfo</legend>
    @using(Html.BeginForm())
    {
        for(int i=0;i<Model.Count;i++)
            {
             <div class="display-label">
                  @Html.LabelFor(model => Model[i].Name)
            </div>
          <div class="display-label">
                  @Html.TextBoxFor(model => Model[i].Name)
            </div>
          <div class="display-label">
                  @Html.LabelFor(model => Model[i].Description)
            </div>
          <div class="display-label">
                  @Html.TextBoxFor(model => Model[i].Description)
            </div>
            }
       <input type="submit" value="submit" />
    }
    
</fieldset>
<p>

Please make sure the binding the correct name for each element. (E.g. [0].Name, [1].name)

If you still have the issue, please share the project on the OneDrive.

Best Regards

Starain Chen

Hi,

Thanks for the reply. The thing is we don’t use Razor for the view. We use a Javascript library and our
action methods receive JSON-encoded data. We didn’t have any problems with structure until now.

I have also tried your example to see how the posted student list data is bound to
List<StudentInfo> parameter of the action and seen that it’s totally different from the JSON-encoded array
data:

[0].Code    code0
[0].Description    <b>dddddddddddd</b>
[1].Code    code1
[1].Description    descr1
[2].Code    code2
[2].Description   

JSON-encoded data:

ss    [{"Code":"code0","Description":"<b>dddddddddddd</b>"},{"Code":"code1","Description":"descr1"},{"Code":"code2"}]

If we move along with your example:

1. I can createupdate a single StudentInfo object honoring the AllowHtml attribute.

2. I can
createupdate multiple StudentInfo objects if I don’t write any Html content on Description property.

3. I can NOT
createupdate multiple StudentInfo objects if I write Html content
on
Description property. I get "A potentially dangerous Request.Form value was detected from the client" error. AllowHtml is NOT taken into account in this case.

I
don’t want to put ValidateInput(false) attribute on the action. I want all fields to be validated except two note fields.

Thanks
in advance

Hi kpaxco,

kpaxco

[{"Code":"code0","Description":"<b>dddddddddddd</b>"},{"Code":"code1","Description":"descr1"},{"Code":"code2"}]

Base on the this code, we can find that the format is incorrect. You are losing the prefix. (E.g. [0].Code)

If you still have the issue, please provide the detail code about how do you serialize the form data or simple project on the OneDrive which have that issue.

Best Regards

Starain

Hi,

Thanks for the reply. But unfortunately we can not change the way that the form data is encoded to JSON. And if I’m not mistaken when people work with a Javascript UI library instead of Razor, this format of encoding is pretty common.

The format that we use worked without a problem until now. Hope that ASP.NET MVC will adjust to this type of JSON encoding (without the index prefix) soon.

Thanks again

Hi,

Please provide the detail code.

Thanks

I tried your scenario when i stringify and post the json it doesn’t work says server error.. at this point AllowHtml isn’t working

You might want to look at

http://stackoverflow.com/questions/81991/a-potentially-dangerous-request-form-value-was-detected-from-the-client

http://www.asp.net/whitepapers/aspnet4/breaking-changes (following..)

ASP.NET Request Validation

The request validation feature in ASP.NET provides a certain level of default protection against cross-site scripting (XSS) attacks. In previous versions of ASP.NET, request validation was enabled by default. However, it applied only to ASP.NET pages (

.aspx

 files and their class files) and only when those pages were executing.

In ASP.NET 4, by default, request validation is enabled for all requests, because it is enabled before the BeginRequest phase of an HTTP request. As a result, request validation applies to requests for all ASP.NET resources, not just .aspx page requests. This includes requests such as Web service calls and custom HTTP handlers. Request validation is also active when custom HTTP modules are reading the contents of an HTTP request.

As a result, request validation errors might now occur for requests that previously did not trigger errors. To revert to the behavior of the ASP.NET 2.0 request validation feature, add the following setting in the 

Web.config

 file:

<httpRuntime requestValidationMode="2.0" />

However, we recommend that you analyze any request validation errors to determine whether existing handlers, modules, or other custom code accesses potentially unsafe HTTP inputs that could be XSS attack vectors.

doesn’t work either.. have to see debug the source code.. didn’t know this could happen with AllowHtml

Leave a Reply