Date validation in the Asp Net Core model?

Asked

Viewed 819 times

2

I have a model and wanted to validate the final date (which should be equal to or greater the initial date)

public class MyModel
{
    [Key]
    public int ModelId { get; set; }

    [Display(Name = "Início")]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")]
    public DateTime? StartDate { get; set; }

    [Display(Name = "Fim")]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")]
    public DateTime? FinishDate { get; set; }

}

Any idea how to validate a field based on another model?

  • you are using dataannotations?

  • I’m using yes

  • @Wallacereis was placed the two versions Aspnetcore changed only the interface class the rest the implementation is equal to previous.

1 answer

2


Version prior to ASPNET CORE

A Custom class that inherits from the abstract class should be created Validationattribute for server validation and the Interface Iclientvalidatable for client validations, the basic example to validate whether one date is greater than or equal to another is:

Create a class and inherit and implement respectively Validationattribute and Iclientvalidatable:

public class DateTimeCompareAttribute : 
        ValidationAttribute, IClientValidatable

{
    public string NameCompare { get; set; }
    public DateTimeCompareAttribute(string nameCompare)
    {
        NameCompare = nameCompare;
    }
    protected override ValidationResult IsValid(object value, 
                                                ValidationContext validationContext)
    {            
        if (validationContext.ObjectInstance != null)
        {
            Type _t = validationContext.ObjectInstance.GetType();
            PropertyInfo _d = _t.GetProperty(NameCompare);
            if (_d != null)
            {
                DateTime _dt1 = (DateTime)value;
                DateTime _dt0 = (DateTime)_d
                     .GetValue(validationContext.ObjectInstance, null);
                if (_dt1 != null &&
                    _dt0 != null &&
                    _dt0 <= _dt1)
                {
                    return ValidationResult.Success;
                }
            }
        }
        return new ValidationResult("Final Date is less than Initial Data");
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
                                                  ModelMetadata metadata, 
                                                  ControllerContext context)
    {
        ModelClientValidationRule rules = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "datetimecompare"
        };

        rules.ValidationParameters.Add("param", NameCompare);            
        yield return rules;
    }
}

After the elaboration of this class you have to configure in the class that will be validated by this attribute as follows:

public class MyModel
{
    [Key]
    public int ModelId { get; set; }

    [Display(Name = "Início")]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")]
    public DateTime? StartDate { get; set; }

    [Display(Name = "Fim")]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")]
    //configuração para verificar se a data é maior ou igual a que foi dita no parâmetro
    [DateTimeCompare("StartDate")] 
    public DateTime? FinishDate { get; set; }

}

this setting already validates the data on the server, but to stay a complete validation is nice add a snippet javascript () to also have client validation, example:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script>
        $.validator.addMethod('datetimecompare', function (value, element, params) {
            return Date.parse(value) >= Date.parse($(params).val());
        }, '');
        $.validator.unobtrusive.adapters.add("datetimecompare", ["param"], 
         function (options) {
            options.rules["datetimecompare"] = "#" + options.params.param;
            options.messages["datetimecompare"] = options.message;
        });
    </script>
}

with these settings will validate the client that is the javascript and that of the server.


Version for ASPNET CORE

To ASPNET CORE has a change in the class of Interface that the person responsible for the validation on the client side is the Interface Iclientmodelvalidator, but, the changes are minimal, note the class DateTimeCompareAttribute:

public class DateTimeCompareAttribute :
        ValidationAttribute, IClientModelValidator
{
    public string NameCompare { get; set; }
    public DateTimeCompareAttribute(string nameCompare)
    {
        NameCompare = nameCompare;
    }
    protected override ValidationResult IsValid(object value,
                                                ValidationContext validationContext)
    {
        if (validationContext.ObjectInstance != null)
        {
            Type _t = validationContext.ObjectInstance.GetType();
            PropertyInfo _d = _t.GetProperty(NameCompare);
            if (_d != null)
            {
                DateTime _dt1 = (DateTime)value;
                DateTime _dt0 = (DateTime)_d
                     .GetValue(validationContext.ObjectInstance, null);
                if (_dt1 != null &&
                    _dt0 != null &&
                    _dt0 <= _dt1)
                {
                    return ValidationResult.Success;
                }
            }
        }
        return new ValidationResult("Final Date is less than Initial Data");
    }

    public void AddValidation(ClientModelValidationContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }            
        context.Attributes.Add("data-val-datetimecompare", ErrorMessageString);
        context.Attributes.Add("data-val-datetimecompare-param", NameCompare);
    }
}

After creating this class the rest continue following the example to version before the ASPNET CORE, because it’s the same way, just remembering the steps:

  • decorating the FinishDate with the DateTimeCompare
  • and adding the javascript ().

References:

  • That’s right there thanks @Virgilio what a great need for a customer validation?

  • @Wallacereis you force the information to go to the server as formatted as possible, and this can be band saving already since your form already has a pre - validation... !!! and do not need to send several times to check. it is a good practice to have, but, the essential is the server that is guarantee of efficiency

Browser other questions tagged

You are not signed in. Login or sign up in order to post.