1

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?

1

1 Answer 1

3

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)
Sign up to request clarification or add additional context in comments.

3 Comments

I know I could use the regex as you have mentioned - it will be used in multiple locations on numerous pages however so for a better design I want a validations folder that will contain all the custom validation classes, so ones for phone number, post/zip codes/dates, etc - thanks for you response though - I will look into it.
Correct. In this case having a custom validator seems appropriate.
Many Thanks - I think it was the placeholders on the page I was missing

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.