Allow User to input HTML in ASP.NET MVC - ValidateInput or AllowHtml
Asked Answered
I

11

123

How can I allow a user to input HTML into a particular field using ASP.net MVC.

I have a long form with many fields that get mapped to this complex object in the controller.

I would like to make one field (the description) allow HTML which I will preform my own sanitation on at a later point.

Ilka answered 1/9, 2010 at 19:4 Comment(1)
For future visitors: IMHO, Chris J or Eugene Bosikov's answers are better than the accepted one for later versions of ASP.NET MVC, especially if you only want to allow HTML in one field.Propagable
M
167

Add the following attribute the action (post) in the controller that you want to allow HTML for:

[ValidateInput(false)] 

Edit: As per Charlino comments:

In your web.config set the validation mode used. See MSDN:

<httpRuntime requestValidationMode="2.0" />

Edit Sept 2014: As per sprinter252 comments:

You should now use the [AllowHtml] attribute. See below from MSDN:

For ASP.NET MVC 3 applications, when you need to post HTML back to your model, don’t use ValidateInput(false) to turn off Request Validation. Simply add [AllowHtml] to your model property, like so:

public class BlogEntry {
    public int UserId {get;set;}
    [AllowHtml] 
    public string BlogText {get;set;}
 }
Modification answered 1/9, 2010 at 19:11 Comment(15)
If you are using .NET 4 you'll also have to set <httpRuntime requestValidationMode="2.0" /> in your web.config file.Xerophthalmia
@Xerophthalmia good point... I will amend my answer to include that and some more information.Modification
but wont that preclude me from being able to use validation on the rest of my Model? I have a large model for this particular page not to mention all of the other models edited by this controller I was hoping to rely heavily on the ModelState and declarative Validation through attributesIlka
@Ilka it will remove all request validation for this action. It will not affect your model validation but all other fields will need to be checked and sanatized as well. You can't do it on a field by field level because the validation is happening at the point when the request is received which is way before the model is validated.Modification
Is there really no solution for .NET 4 that doesn't include downgrading the request validation mode?Murphey
@Murphey check out the MSDN link I posted... it doesn't need to be there but it is an option depending on the behaviour that they are after.Modification
MSDN (msdn.microsoft.com/de-de/magazine/hh708755.aspx) says, that you shouldn't use ValidateInpute and take AllowHtmlAttribute instead. (Did'nt found the English version)Apomixis
@sprinter252 Thanks +1 and english version can be reach by choosing language from top of the page or this link: msdn.microsoft.com/en-us/magazine/hh708755.aspxTaunt
Made edit to hopefully address the 3 down votes that were recently made... it was a 4 year old answer :)Modification
[AllowHtml] attribute only gives potentially dangerous request error.Syllogism
Added another upvote to offset blind downvoting Kelsey. Sad that Stack users don't look at the date of the answer and take that into consideration when deciding if the answer was correct at the time of posting.Antler
@Kelsey: Thanks for your complete answer :)Pincers
Muchas gracias, me sirvio mucho tu respuesta. La que se acomodo fue el atributo AllowHtmlDecry
Is there any way to do this in web.config or elsewhere, everytime I update my ef6 model it wipes them all outBiographical
@Biographical Typically, you do not use your EF model as your view model. You would write a separate class that represents the actual data for your CRUD operations. This way when your EF6 model is regenerated, nothing is lost. You should also slim the models down to have only the properties you need to perform the task at hand.Wolverine
F
132

What about [AllowHtml] attribute above property?

Fizgig answered 30/7, 2012 at 12:17 Comment(9)
This seems like a much better way to me, avoiding changing any global behaviour. I've just solved my problem by adding this attribute to a property on my model.Pandolfi
Totally agree with Chris solution here, there is no reason to disable the html validation for the whole application if you just need one property in a model to be able to accept html input. Removing the validation in the web.config will open a big security hole in your app.Latticed
Unfortunately this does not work if you are using MetadataTypeAttributeHermon
@dav_i: This solution works fine with MetadataTypeAttribute and is preferable as it only allows HTML on the individual fields rather than the entire object.Keffiyeh
@TrueBlueAussie, I have been trying for hours in my mvc 4.0 environment and although AllowHtml should work it doesnt. I have had to admit defeat and go with a less secure option which is pants. The AllowHtml just doesnt seem to work with the use of MetadataTypeAttributeOutfight
It also won't work if you access the request field containing the html before the DefaultModelBinder does, as in a custom IModelBinder for example.Pollute
@Pollute Yes, that attribute is supposed to work only with the DefaultModelBinder and I assumed that it is obvious :)Fizgig
[AllowHtml] attribute only gives potentially dangerous request error.Syllogism
Works on my machine. Thanks cryss!Antler
B
43

Add to model:

using System.Web.Mvc;

And to your property

        [AllowHtml]
        [Display(Name = "Body")]
        public String Body { get; set; }

This code from my point the best way avoid this error. If you are using HTML editor you will not have security issues because it already restricted.

Blasto answered 24/3, 2013 at 21:5 Comment(0)
P
9

Adding [AllowHtml] on the specific property is the recommended solution as there are plenty of blogs and comments suggesting to decrease the security level, which should be unacceptable.

By adding that, the MVC framework will allow the Controller to be hit and the code in that controller to be executed.

However, it depends on your code, filters, etc. how the response is generated and whether there is any further validation that might trigger another similar error.

In any case, adding [AllowHtml] attribute is the right answer, as it allows html to be deserialized in the controller. Example in your viewmodel:

[AllowHtml]
public string MessageWithHtml {get; set;}
Positivism answered 6/5, 2015 at 22:19 Comment(0)
C
9

I faced the same issue although i added [System.Web.Mvc.AllowHtml] to the concerning property as described in some answers.

In my case, i have an UnhandledExceptionFilter class that accesses the Request object before MVC validation takes place (and therefore AllowHtml has not effect) and this access raises a [HttpRequestValidationException] A potentially dangerous Request.Form value was detected from the client.

This means, accessing certain properties of a Request object implicitly fires validation (in my case its the Params property).

A solution to prevent validation is documented on MSDN

To disable request validation for a specific field in a request (for example, for an input element or query string value), call the Request.Unvalidated method when you get the item, as shown in the following example

Therefore, if you have code like this

var lParams = aRequestContext.HttpContext.Request.Params;
if (lParams.Count > 0)
{
  ...

change it to

var lUnvalidatedRequest = aRequestContext.HttpContext.Request.Unvalidated;

var lForm = lUnvalidatedRequest.Form;
if (lForm.Count > 0)
{
  ...

or just use the Form property which does not seem to fire validation

var lForm = aRequestContext.HttpContext.Request.Form;
if (lForm.Count > 0)
{
  ...
Cloddish answered 24/11, 2015 at 9:48 Comment(1)
Thanks! Request.Unvalidated was the only solution that worked for me.Inositol
H
4

If you need to allow html input for action-method parameter (opposed to "model property") there's no built-in way to do that but you can easily achieve this using a custom model binder:

public ActionResult AddBlogPost(int userId,
    [ModelBinder(typeof(AllowHtmlBinder))] string htmlBody)
{
    //...
}

The AllowHtmlBinder code:

public class AllowHtmlBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var request = controllerContext.HttpContext.Request;
        var name = bindingContext.ModelName;
        return request.Unvalidated[name]; //magic happens here
    }
}

Find the complete source code and the explanation in my blog post: https://www.jitbit.com/alexblog/273-aspnet-mvc-allowing-html-for-particular-action-parameters/

Hett answered 11/6, 2018 at 11:27 Comment(2)
Unvalidated seems to be only available in framework 4.5 and above.Febricity
@Febricity correct! Please check this modified solution. #59483784Gabey
F
3

URL Encoding the data works as well for me

For example

var data = '<b>Hello</b>'

In Browser call encodeURIComponent(data) before posting

On Server call HttpUtility.UrlDecode(received_data) to decode

That way you can control exactly which fields area allowed to have html

Foretooth answered 20/8, 2018 at 23:57 Comment(1)
easiest way so farEpiscopal
D
2

You Can Use [AllowHtml] To Your Project For Example

 [AllowHtml]
 public string Description { get; set; }

For Use This Code To Class Library You Instal This Package

Install-Package Microsoft.AspNet.Mvc

After Use This using

using System.Web.Mvc;
Dentation answered 2/12, 2019 at 12:34 Comment(0)
S
1

I have faced this problem during development of a E-Commerce site using NopCommerce, I got this solution by 3 different ways as like the previous answers. But according to the NopCommerce structure I didn't found those three at a time. I have just seen that there they are using just [AllowHtml] and it's working fine except any problem. As previously asked question

Personally I don't prefer [ValidateInput(false)] because i's skipping total model entity checking, which is insecure. But if anyone just write have a look here

[AllowHtml] 
public string BlogText {get;set;}

then it just skip only single property, and just allow only particular property and check hardly all other entities. Therefore it seems preferable towards mine.

Stillas answered 12/1, 2017 at 6:45 Comment(0)
W
1

In my case, the AllowHtml attribute was not working when combined with the OutputCache action filter. This answer solved the problem for me. Hope this helps someone.

Walrath answered 17/2, 2017 at 21:32 Comment(0)
G
0

None of the answers here worked for me unfortunately.

I ended up using Custom Model Binding and used a third-party Sanitizer.

See my self-answered question here.

Gabey answered 26/12, 2019 at 2:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.