Question

I'm using Validation.Add() and the Html.TextBox() (and related) helpers in conjunction with unobtrusive JavaScript error checking and am very pleased with the results. It covers the server and client side with one set of code and generally I've been able to achieve everything I need to.

I've hit a bit of a snag though in that there are certain times that you need to run your own logic to establish an error case. If this error relates directly to a field it would be nice to manually flag that field as the source of the error with an arbitrary error message - something I'm fairly sure there is no way to do out of the box. To clarify what I mean, an example is a field for a username that needs to check whether the username is already in use - if it is, an error is generated.

At the moment, I'm adding it to the form error collection using Validation.AddFormError(), which works, but displays the error only in the summary. Seeing as, in the example above, the error is obviously related to the Username field, it seems logical to be able to tie that error to the appropriate field name (and show it in the right place).

Should I just derive from RequestFieldValidatorBase and make a validator that only returns false to IsValid()? Obviously, being a server side check I don't expect to check for it on the client side, although I know that too could be possible by writing a more specific validator and a plugin for the validation system, exposing more data- attributes and performing an AJAX check. What I'm interested in for this question is a more general purpose solution: marking a specific field as the source of a server side error.

Hopefully that makes sense. What would people recommend as the best approach to this problem?

Was it helpful?

Solution

Sorry for the necromancer answer, but I recently bumped into this, and I have found a simpler solution. ModelStateDictionary supports this feature natively. Simply use ModelState instead of Validation and you no longer need the custom validator, the initializer method, or any other artifacts; everything is baked right in:

Trigger validation on a specific form element

if (!usernameIsValid)
{
    ModelState.AddError("username", "That username is already taken.");
}

ModelState also lets you add form-wide validation error messages, just like Validation:

Trigger validation on the whole form

if (password != confirmation)
{
    ModelState.AddFormError("Password and confirmation password do not match.");
}

Another advantage of this approach is that ModelState works in both ASP.NET Web Pages and ASP.NET MVC. On the other hand, Validation is proprietary to ASP.NET Web Pages, which might complicate things if you ever wish to migrate your project to MVC.

Resources

OTHER TIPS

I thought I'd come back and post what I implemented in the end, in case it might help anybody else or in case anybody can suggest any improvements.

I added a custom validator that I named Throw to App_Code:

public class Throw : RequestFieldValidatorBase
{
    public Throw(string errorMessage)
        : base(errorMessage)
    { }

    protected override bool IsValid(System.Web.HttpContextBase httpContext, string value)
    {
        return false;
    }
}

Then added an initialiser method for it so that I could create instances of them inline in the same way that the built in validators work (also added to App_Code):

public static class CustomValidator
{
    public static Throw Throw(string errorMessage)
    {
        return new Throw(errorMessage);
    }
}

Then in my content pages I can do things like:

if (!usernameIsValid)
{
    Validation.Add("username", CustomValidator.Throw("That username is already taken."));
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top