Brosteins

Developers, Technology Evangelists, Bros.

MVC Validation Extensions

What are MVC Validation Extensions?

MVC Validation Extensions is a library that builds upon ASP.NET MVC by providing additional validation attributes to use.

 

 

Features

  • Familiar usage by extending ASP.NET MVC data annotations
  • Client and server validation methods
  • Dynamic comparison of dates or numeric fields
  • Model attributes

Getting Started
To get started with the additional attributes just install the MVCValidationExtensions nuget package into your solution.  Add the appropriate attributes to your models.

Additional Implemented Attributes

  • Comparison – Validates that the property meets the comparison with the specified other property
    • GreaterThan
    • GreaterThanEqualTo
    • LessThan
    • LessThanEqualTo
  • RequiredIf – Causes the property to be required if the specified other property is not null
  • RequiredIfValue – Causes the property to be required if the specified other property is equal to the specified other value
  • RequiredIfAnyValue – Causes the property to be required if the specified other property is equal to any of the specified other values
  • RequiredIfEmpty – Causes the property to be required if the specified other property is empty (whitespace is considered empty)

Usage
Using the MVC Validation Extensions is simple because they are used the same way the current validation attributes are.

Given the following Model…

public class TestModel
    {
        [RequiredIf("RequiredIntControl")]
        public int? SomeIntThatMightBeRequired { get; set; }

        [RequiredIfValue("RequiredIntControl", "15")]
        public int? SomeRequiredIfValue { get; set; }

        public string RequiredIntControl { get; set; }

        [RequiredIfAnyValue("RequiredIfAnyValueControl", new []{"ValOne", "ValTwo", "ValThree"})] 
        public int? RequiredIfAnyValue { get; set; } 
        public string RequiredIfAnyValueControl { get; set; }
        [DisplayName("> Hidden Int")]
        [GreaterThan("HiddentInt")]
        public int? SomeValue { get; set; }

        [Required]
        [GreaterThan("SomeValue", ErrorMessage = "Overriding the error message.")]
        public int? RequiredInt { get; set; }

        [Required]
        [DisplayName("< Date")]
        [LessThan("SomeOtherDate")]
        public DateTime? SomeDate { get; set; }

        [DisplayName("<= Some Other Date")]
        [LessThanEqualTo("HiddenDateTime")]
        public DateTime? SomeOtherDate { get; set; }

        [DisplayName(">= Kendo Date")]
        [GreaterThanEqualTo("KendoDateOther")]
        public DateTime? KendoDate { get; set; }

        public int? HiddentInt { get; set; }
        public DateTime? HiddenDateTime { get; set; }
        public DateTime? KendoDateOther { get; set; }
    }

We get the following results…

 

mvc validation extensions example

 

mvc validation extensions 1.1.2

Required and valid.

Share

22 comments for “MVC Validation Extensions

  1. kam
    February 22, 2016 at 12:25 pm

    how to do group validation?

    • March 2, 2016 at 10:30 am

      Kam,

      Can you be more specific as to the scenario that you are having trouble validating?

  2. Stephen Welch
    April 6, 2016 at 2:28 pm

    I am using your MVC validation extensions within a modal that is loaded via ajax and showing/hiding controls based on selections. Since the form is reloading, in order for the unobtrusive validation to occur I had to manually call the unobtrusive jquery validation:

    $(document).on(‘click’, ‘#btnSave’, function () {
    $.validator.unobtrusive.parse(“#preceptorform”);
    });

    but this doesnt seem to work with your mvcvalidationextensions.unobtrusive.js functionality since the validator works on first load, then stops working the second time. Is there a way that I can call your checks within the button click of the modal?

    • April 8, 2016 at 9:39 am

      Stephen,

      This is what I typically do after loading in a new form via Ajax:

      var form = $(‘form’);
      form.removeData(‘validator’);
      form.removeData(‘unobtrusiveValidation’);
      $.validator.unobtrusive.parse(form);

      This will parse the entire form which I have not had any issues with. If you still have issues are you able to setup a jsfiddle or jsbin and I can help you take a closer look?

  3. Stephen Welch
    April 8, 2016 at 7:18 pm

    thank you! This worked!

  4. Alan Kaeser
    May 18, 2016 at 3:31 pm

    Does this work with Html.EditorFor in Razor Forms:
    Here is my Model:
    [DisplayName(“Start Date”)]
    [Required(ErrorMessage=”A Start Date is Required”)]
    public DateTime? StartDate
    {
    get; set;
    }

    [DisplayName(“End Date”)]
    [Required(ErrorMessage = “An End Date is Required”)]
    [GreaterThanEqualTo(“StartDate”, ErrorMessage =”End Date Must be later than the StartDate”)]
    public DateTime? EndDate
    {
    get; set;
    }

    Here is my CSHTML:

    @Html.ValidationSummary(true, “”, new
    {
    @class = “text-danger”
    })

    @Html.LabelFor(m => m.StartDate, new
    {
    @class = “col-md-3 control-label”
    })

    @Html.EditorFor(m => m.StartDate)

    @Html.ValidationMessageFor(m => m.StartDate, “”, new
    {
    @class = “text-danger”
    })

    @Html.LabelFor(m => m.EndDate, new
    {
    @class = “col-md-3 control-label”
    })

    @Html.EditorFor(m => m.EndDate)

    @Html.ValidationMessageFor(m => m.EndDate, “”, new
    {
    @class = “text-danger”
    })

    I don’t get any validation message if I put a start date > the end date.
    I have jquery.validate.unobstrusive loaded with my bundles. I get an error if I don’t enter anything in the date fields.

    • Alan Kaeser
      May 20, 2016 at 4:37 pm

      I figured out the issue. I didn’t have the script loaded in my bundle. Not sure if I ever saw that in the installation instructions.

  5. Janet
    June 30, 2016 at 4:42 pm

    What is the best method to use for determine if the checkbox is true. We are try RequiredIFValue(); but I doesn’t seem to work

    • July 17, 2016 at 9:30 am

      You can use the RequiredIf attribute for checkboxes. If you are setting different values on checkboxes other than default True/False you’d want to use RequiredIfValue.

  6. Rahul Savaliya
    December 8, 2016 at 1:42 am

    I have used RequiredIFValue in bool? property. and seems like it is not working. can you suggest way how to apply RequiredIFValue in bool? property.

    • December 13, 2016 at 9:31 am

      Is there any way you can post your model and view code to Github perhaps?

  7. Tirthak
    December 8, 2016 at 7:03 am

    How can we use same attribute multiple times on same property?
    For example :-

    RequiredIf(someproperty1,1)
    RequiredIf(someproperty2,2)
    RequiredIf(someproperty3,3)
    public string property {get; set;}

    • December 13, 2016 at 9:33 am

      Unfortunately it will not work like this. This would require a new extension.

  8. Ivy B
    December 29, 2016 at 10:08 am

    How can you skip form validation for those html elements that are hidden? I have two elements, Min and Max that get validated even if they are hidden which makes my form put out an error.

    • January 3, 2017 at 10:15 am

      This is actually probably a better question for jQuery validate, however, the default settings of jQuery validate are set to ignore hidden fields so anything hidden should not be causing validation.

      They best I can do without seeing your full model and view code is that you can override or reconfigure jQuery validate with something like the following:

      var inputForm = $(‘form’);

      if ($.data(inputForm[0], ‘validator’)) {
      $.data(inputForm[0], ‘validator’).settings.ignore = ‘:hidden’;
      }

      Where ‘:hidden’ is a selector as to the elements that you want ignored.

  9. Stephen Welch
    March 23, 2017 at 10:07 am

    Hi Nick!

    I have a viewmodel like this:

    Public Class nomination
    {
    [DataType(DataType.Upload)]
    [Required(ErrorMessage =”You must upload a letter.”)]
    [FileType(“doc,docx,pdf,DOC,DOCX,PDF”, ErrorMessage =”Must upload DOC, DOCX, or PDF file.”)]

    public HttpPostedFileBase FileUpload { get; set; }

    [Required]
    public List committees { get; set; } = Helpers.helpers.getCommittees();
    }

    public class committeeVM
    {
    public int commid { get; set; }
    public string commname { get; set; }

    public bool isselected { get; set; }
    }

    TheCommitteeVM is the results of a checkbox list (isselected is true if one is selected…)

    I am needing to require the file upload IF one of the nominations.Committees.isselected = true and the nominations.Committees.commid is a specific value, say 2 or 3.

    Is there a way to use the extensions to accomplish this when the property is part of a list object within the viewmodel?

    • April 3, 2017 at 12:42 pm

      Unfortunately the validation extensions won’t be able to pull from a collection so this is something that you will need to check manually.

  10. Chris
    May 4, 2017 at 5:26 pm

    Nick, I downloaded your extension into my project and I’m trying to trigger the validation in a Modal window. Regular data annotations will display ok, but the ones from your extension break the modal and refresh the page and display without styles.

    MODEL LOOKS LIKE THIS:

    public int ContactID { get; set; }
    [Required]
    [DisplayName(“Category”)]
    public int CategoryID { get; set; }
    [Required]
    [DisplayName(“Level”)]
    public int LevelTypeID { get; set; }

    [RequiredIfValue(“CategoryID”, “1”)]
    [DisplayName(“First Name”)]
    public string FirstName { get; set; }

    [RequiredIfValue(“CategoryID”, “1”)]
    [DisplayName(“Last Name”)]
    public string LastName { get; set; }

    [RequiredIfValue(“CategoryID”, “2”)]
    public string Company { get; set; }

    ____________________________________________

    PARTIAL VIEW LOOKS LIKE THIS:

    @model AutomationPro.Contact

    @*http://~/Scripts/jquery.validate.unobtrusive.min.js*@

    $(“#firstname1”).hide();
    $(“#firstname2”).hide();
    $(“#firstname3”).hide();
    $(“#lastname1”).hide();
    $(“#lastname2”).hide();
    $(“#lastname3”).hide();
    $(“#company1”).hide();
    $(“#company2”).hide();
    $(“#company3”).hide();

    $(document).ready(function () {
    $(‘#category’).on(‘change’, function () {
    if (this.value == ‘1’)

    {
    $(“#firstname1”).show();
    $(“#firstname2”).show();
    $(“#firstname3”).show();
    $(“#lastname1”).show();
    $(“#lastname2”).show();
    $(“#lastname3”).show();
    $(“#company1”).hide();
    $(“#company2”).hide();
    $(“#company3”).hide();

    }
    else {
    $(“#firstname1”).hide();
    $(“#firstname2”).hide();
    $(“#firstname3”).hide();
    $(“#lastname1”).hide();
    $(“#lastname2”).hide();
    $(“#lastname3”).hide();
    $(“#company1”).show();
    $(“#company2”).show();
    $(“#company3”).show();

    }

    });
    });

    ×
      Contact

    @using (Html.BeginForm(null, null, FormMethod.Post, new { @enctype = “multipart/form-data”, id = “createContactchoice” }))
    {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true, “”, new { @class = “text-danger” })
    @Html.HiddenFor(model => model.ContactID)
    @Html.HiddenFor(model => model.LevelTypeID)

    Category

    @Html.DropDownList(“CategoryID”, ViewBag.Categories as SelectList, String.Empty, new { @class = “form-control”, id = “category” })
    @Html.ValidationMessageFor(model => model.CategoryID, “”, new { @class = “text-danger” })


    @Html.EditorFor(model => model.ContactTypes)

    First Name

    @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = “form-control” } })
    @Html.ValidationMessageFor(model => model.FirstName, “”, new { @class = “text-danger” })

    Last Name

    @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = “form-control” } })
    @Html.ValidationMessageFor(model => model.LastName, “”, new { @class = “text-danger” })

    Company

    @Html.EditorFor(model => model.Company, new { htmlAttributes = new { @class = “form-control” } })
    @Html.ValidationMessageFor(model => model.Company, “”, new { @class = “text-danger” })

     
    Cancel


    }

    • May 12, 2017 at 5:00 pm

      I’m assuming the partial view is the one that is loaded into the modal. There shouldn’t be any issues with the extensions in a modal or a popup. Can you open your dev tools and check to see if you have any javascript errors in the console when the modal opens up or when the validation should be firing?

Leave a Reply

Your email address will not be published. Required fields are marked *