65.9K
CodeProject is changing. Read more.
Home

Validating User Input Containing HTML tags in ASP.NET MVC

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.64/5 (8 votes)

Nov 19, 2012

CPOL

2 min read

viewsIcon

45038

downloadIcon

526

If you need that validation message saying: "Input field should not contain HTML...” then this short tip is for you!

Introduction

There was a need for checking that user input does not contain any tags and display a corresponding validation message. As you may know ASP.NET has a built in feature for verifying if the HTTP request has a potentially dangerous content, that is called Request validation. By default it is true in ASP.NET MVC for security reasons.

So how do we overpass this and create our custom validation mechanism for verifying that user input contains HTML code...

I have attached a sample project where this mechanism is implemented. This tip/example gives only the basic understanding of how to implement your own custom validation attribute for verifying the input. Also only server side validation happens in this example.

Let the code speak

I'll shortly describe the code from the sample project below:

First of all we have to create a custom validation attribute for checking if the model's property value has any HTML/XML tags. Let's call our custom attribute DisallowHtmlAttribute. To implement our validation logic we should override the IsValid method and place the logic there. Here is how it looks:

public class DisallowHtmlAttribute : ValidationAttribute 
{
   protected override ValidationResult IsValid(object value, ValidationContext validationContext)
   {
	if (value == null)
           return ValidationResult.Success;

        var tagWithoutClosingRegex = new Regex(@"<[^>]+>");

        var hasTags = tagWithoutClosingRegex.IsMatch(value.ToString());

        if (!hasTags)
            return ValidationResult.Success;

        return new ValidationResult("The field cannot contain html tags");
   }
}

Okay, we've created our custom validation attribute, however we should have some mechanism for adding this validation attribute to all properties of the model that is passed to the view.

This can be done by creating our own custom DataAnnotationsModelValidatorProvider that will be adding and returning our DisallowHtmlAttribute to the list of modal validators. Let's call it DisallowHtmlMetadataValidationProvider and let's check its implementation:

public class DisallowHtmlMetadataValidationProvider : DataAnnotationsModelValidatorProvider
{
    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, 
       ControllerContext context, IEnumerable<Attribute> attributes)
    {
        if (attributes == null)
            return base.GetValidators(metadata, context, null);
        if (string.IsNullOrEmpty(metadata.PropertyName))
            return base.GetValidators(metadata, context, attributes);
        //DisallowHtml should not be added if a property allows html input
        var isHtmlInput = attributes.OfType<AllowHtmlAttribute>().Any();
        if (isHtmlInput)
            return base.GetValidators(metadata, context, attributes);
        attributes = new List<Attribute>(attributes) { new DisallowHtmlAttribute() };
        return base.GetValidators(metadata, context, attributes);
    }
}

Now we have to add DisallowHtmlMetadataValidationProvider to the MVC's current application validator provider. Such things are usually done in Global.asax:

protected void Application_Start()
{ 
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    //registering our custom model validation provider
    ModelValidatorProviders.Providers.Clear();
    ModelValidatorProviders.Providers.Add(new DisallowHtmlMetadataValidationProvider());
}

We are almost there. The only thing we have to do now is to disable the request validation, but first let's see how currently the site behaves when the user's input contains HTML/XML tags. Let's enter something like this:

This is what we get after posting data to the server:

This is the correct behavior because we haven't disabled the request validation in the application. We can easily disable the request validation for all Controller and Actions by registering ValidateInputAttribute with the false parameter in the global action filters in the Global.asax file.

filters.Add(new ValidateInputAttribute(false));

Or if you need to disable Request validation only for a specific controller or action, just decorate it with:

[ValidateInput(false)]

Now we are done and every time the user input contains an HTML or XML tag he'll see a validation message:

Simple as that!