Ctrl_Alt_Defeat
Ctrl_Alt_Defeat

Reputation: 4009

ASP.NET MVC 3 - Custom Validator

I am trying to implement a custom validator for phone number on an ASP.NET MVC 3 App I am writing. I have wriiten the code for the custom validator as below

public class PhoneNumberValidator : ValidationAttribute 
{


    public PhoneNumberValidator() : base("The Phone Number is not Valid")
    {
    }
    public override bool  IsValid(object value)
    {
        if (value != null)
        {
            string phonenumber = value.ToString();

            var regex = new Regex(@"^(?:[0-9]+(?:-[0-9])?)*$");

            if (regex.IsMatch(phonenumber))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        return false;
    }
}

Then in my Model class I have the following :

    [Display(Name = "PhoneNumber")]
    [Required(ErrorMessage = "Is Phone Number Required")]
    [PhoneNumberValidator]
    public string PhoneNumber { get; set; }

However when I run my app and click the proceed button on the page it does not throw an error if the value entered is letters although if I set a breakpoint I can see that the value is being read in to string phonenumber ok. Am I missing something simple?

Upvotes: 1

Views: 1537

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039438

You seem to be reinventing a wheel. Why not use the existing regex validator:

public class MyViewModel
{
    [Display(Name = "PhoneNumber")]
    [Required(ErrorMessage = "Is Phone Number Required")]
    [RegularExpression(@"^(?:[0-9]+(?:-[0-9])?)*$")]
    public string PhoneNumber { get; set; }
}

This being said validation is triggered by the model binder, so make sure that the controller action you are submitting the form to takes the view model as argument:

[HttpPost]
public ActionResult Process(MyViewModel model)
{
    if (!ModelState.IsValid)
    {
        // the model is invalid => redisplay view
        return View(model);
    }

    // at this stage the model is valid => you could do some processing here 
    // and redirect
    ...
}

or use the TryUpdateModel method (personally I prefer the previous approach though):

[HttpPost]
public ActionResult Process(FormCollection some_Dummy_Parameter_Thats_Not_Used_At_All_But_Which_We_Need_To_Avoid_The_Method_Overloading_Error_With_The_GET_Action_Which_Has_The_Same_Name)
{
    var model = new MyViewModel();
    if (!TryUpdateModel(model))
    {
        // the model is invalid => redisplay view
        return View(model);
    }

    // at this stage the model is valid => you could do some processing here 
    // and redirect
    ...
}

Also in order to display the error message somewhere make sure that you have a corresponding placeholder in your view:

@Html.EditorFor(x => x.PhoneNumber)
@Html.ValidationMessageFor(x => x.PhoneNumber)

or use a validation summary helper:

@Html.ValidationSummary(false)

Upvotes: 3

Related Questions