How to validate a text input for only printable ASCII characters in ASP.NET MVC

01 Mar 2016

Let’s dive right in, plain and simple: for some reason, you need to make sure that your users don’t enter any non-printable characters into a text input field on a form. Maybe the data needs to travel to far reaches of the known universe, to a remote ancient banking backend system that runs on COBOL and mainframes (fueled by the energy of a dying brown dwarf). Or maybe the column in the database where this data is going to end up has never heard of Unicode. Or maybe that’s just one of those unexplainable, irrational so-called “business rules”, that some aspiring manager somewhere up in the ranks decided to implement.

Good old friend, Regular Expression

ASP.NET MVC comes with a plenty of inbuilt validators, and RegularExpression is one of them. I will spare you the lengthy details of how validation works in ASP.NET MVC, if you’re interested in the theory, check out this article.

All we need to do is to chuck a [RegularExpression] validation attribute on our model and specify a couple of parameters:

public class AccountModel
{
    [Required]
    [RegularExpression("[ -~]+", // Regular expression to use for validation
                       // Error message to display
                       ErrorMessage = "Please use only printable English characters")]
    [Display(Name = "Account name")]
    public string AccountName { get; set; }
}

The value parameter for the regular expression attribute deserves a bit of explanation. If you look at the ASCII table, you will see that printable part of the table starts with the space character ( ) and ends with the tilde character, that is ~.

We’re using the character class regex in here, specifying the range of acceptable characters starting from space and ending with the tilde: [ -~]. Dash character serves here as a separator, essentially saying: “match all characters starting from space and ending with tilde”. In order to match more than just one character, we specify +, which is a repetition operator.

One big catch

There’s, at least, one more way of specifying the filtering regex for the [RegularExpression] attribute - instead of including only printable characters, you can try to exclude non-printable ones. So your regular expression would look something like this: [^\x00-\x7F]+. This is actually quite a bad idea if you are ever going to use FluentValidation. When this regex is translated to JavaScript statement and executed, it’s going to produce the following error:

Uncaught SyntaxError: Invalid regular expression: /[^�-]/: Range out of order in character class

So instead of filtering out non-printable characters explicitly, just stick to checking that all characters are, in fact, printable.

Controller code

That’s really it. What’s remaining is to see how this is getting validated in the controller.

//
// 2. Action method for handling user-entered data when 'Update' button is pressed.
//
[HttpPost]
public ActionResult UpdateAccount(AccountModel model)
{
    // In case everything is fine - i.e. "AccountName" is entered and valid,
    // redirect the user to the "ViewAccount" page, and pass the account object along via Session
    if (ModelState.IsValid)
    {
        Session["AccountModel"] = model;

        // In here you can add saving of object to a database

        return RedirectToAction("ViewAccount");
    }

    // Validation failed, something is not right. Re-render the registration page, keeping user-entered data
    // and display validation errors
    return View("Index", model);
}

Enabling FluentValidation

If you want to add client-side JavaScript validation, refer to my earlier article, “How to use Bootstrap 3 validation states with ASP.NET MVC Forms”.

Downloading the code

You can download the code for this article from GitHub (it comes with FluentValidation enabled already!). Here’s the zip file with complete source code, or you can browse it on GitHub.

But Wait, There’s More!

I hope this article helped you to move forward in your project work.

You can probably recall a time when you were stuck on some problem and the solution seemed so close, yet it took hours to figure it out. And when you eventually did that, it was something so infuriatingly stupid, you might have wanted to punch the monitor.

Do you want to avoid wasting your time on stupid bugs and traps in .NET? Subscribe to my mailing list and save HOURS of your life - I never spam, and I only send useful and actionable advice.


comments powered by Disqus