3

I am trying to validate a phone number which is contained over two fields.

The first field displays the area code and the other field displays the remaining phone number digits.

The requirements are:

  1. They are both required.
  2. They must be numeric.
  3. The area code field must be a maximum of 6 digits and the phone number field must be a maximum of 10 digits.

A single message is required to be displayed for both fields. For example, if the area code was missing but the telephone number was provided then a single message should be displayed after both fields stating "Please enter a telephone number.".

The model I currently have is similar to:

public class Customer
{
    //...other fields here

    public string AreaCode { get; set; }

    public string PhoneNumber { get; set; }
}

I cannot implement the telephone as a single field with a regular expression or simlar.

There is a similar question to this here (and also kind of similar to here) where the answer recommends creating a custom validation attribute (in this case named MultiFieldRequired) to specify the names of the fields which are required in the attribute. The validation attribute then uses reflection to check the values of the other properties to report if there is an error.

For example, in the case of the above model I believe I should have:

public class Customer
{
    //...other fields here

    public string AreaCode { get; set; }

    [MultiFieldRequired("AreaCode", "PhoneNumber", ErrorMessage="Please enter a phone number")]
    public string PhoneNumber { get; set; }
}

However, I have come across a small problem with the provided solution. The error returned by the custom validation attribute is only reported against the field which has the data annotation (PhoneNumber is the model above). Therefore, if the AreaCode is not entered by the user but the PhoneNumber is supplied, the error is reported against the PhoneNumber field and not the AreaCode. Additionally, if you are using the css supplied with the visual studio Internet project the supplied PhoneNumber field will be displayed in red whilst the invalid area code is displayed as white (not showing an error) so this looks a little odd.

Does anyone have a way to correct this colouring behaviour or a way that I can report an error message if either field is in error (using the correct colouring on the fields)?

Thank you in advance.

Community
  • 1
  • 1
Dangerous
  • 4,818
  • 3
  • 33
  • 48

2 Answers2

3

Apply the attribute on both and have only one ValidationMessageFor (anyone) and place it where you want to show the message (from the post it seems you want only one error message).

public class Customer
{
    //...other fields here

    [MultiFieldRequired("AreaCode", "PhoneNumber", ErrorMessage="Please enter a phone number")]
    public string AreaCode { get; set; }

    [MultiFieldRequired("AreaCode", "PhoneNumber", ErrorMessage="Please enter a phone number")]
    public string PhoneNumber { get; set; }
}

View

    <div class="editor-label">
        @Html.LabelFor(model => model.AreaCode)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.AreaCode)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.PhoneNumber)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.PhoneNumber)
        @Html.ValidationMessageFor(model => model.PhoneNumber)
    </div>
amit_g
  • 30,880
  • 8
  • 61
  • 118
  • 1
    I'm not too sure how the implementation is working in the example here. The only way I could get this to work is to add the attribute above one of the properties like so `[MultiFieldRequired(new string[3]{"Phone1", "Phone2", "Phone3"}, ErrorMessage ="Phone# required")]` ------The code only accepts an array. I'm not sure how people are using these comma separated strings and having it work. – ganjeii Aug 16 '16 at 17:57
  • I agree, syntax will not allow to compile the things and ganjeii is right – Gaurav123 Sep 05 '16 at 07:22
1
[MultiFieldRequired("AreaCode", "PhoneNumber", ErrorMessage="Please enter a phone number")]
public class Customer
{
    //...other fields here

    public string AreaCode { get; set; }

    public string PhoneNumber { get; set; }
}

The Multi field required needs to be put over the class, not a single property. If you look at the implementation, it is looking at the object that is passed in, and iterating over its properties.

Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
  • I'm not quite sure this is correct? If you look at the text above Scotts answer it says "This allowed me to implement this at the property level instead of the model level...". Additionally, in the second (similar-ish) example that I provide, Darin Dimitrov has given an example of the attribute used at the property level (above the email property). Although both answers iterate over the properties, I think that the error is intended to be reported at property level, not model level. – Dangerous Nov 04 '11 at 18:43
  • @Dangerous Darin's example is better, I'll look into it a bit further. But I don't understand why you'd want to define it on a single property when it affects others. – Yuriy Faktorovich Nov 04 '11 at 19:05
  • Thankyou but I didn't want to define the validation at model level as I wanted to report the error against a property (or property group in this case). I wanted any error message to appear to the right of (or underneath) the two phone number fields. As I will also have other phone number fields for this model it is difficult to report the errors against the properties using model level validation. I believe jquery lets you define property groups for user validation in this way (don't quote me on this) but it cannot be with mvc3 data annotations without defining custom data annotations. – Dangerous Nov 07 '11 at 19:05