简体   繁体   中英

ASP.Net MVC : How to add code for client side validation using unobtrusive library for my date validation

i had a requirement as a result user will not be able to enter old days or back days. if enter then validation will occur at server side and proper error message will be thrown to client if date is old or back date.

my server side code as follows but i do not know how to validate the date at client side using unobtrusive library which validate date and stop form submitting to server if dates are found in back or old dates.

my model code

using System.ComponentModel.DataAnnotations;

    public class DateValTest
    {
        [Display(Name = "Date of birth")]
        [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
        [MyDate(ErrorMessage = "Back date entry not allowed")]
        public DateTime ? DateOfBirth { get; set; }
    }

i use custom attribute called MyDate which extends Validation Attribute class to validate my date to restrict old or back date entry.

class code for MyDate

public class MyDateAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        DateTime _dateJoin = Convert.ToDateTime(value);
        if (_dateJoin >= DateTime.Now)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult(ErrorMessage);
        }
    }  
}

here is my sample controller code

public class DatValController : Controller
{
    // GET: DatVal
    public ActionResult Index()
    {
        DateValTest d = new DateValTest();
        return View(d);
    }

    [HttpPost]
    public ActionResult Index(DateValTest d)
    {
        //DateValTest d = null;
        if (ModelState.IsValid)
        {
            //d = new DateValTest();
        }
        return View(d);
    }
}

and view code

@model AuthTest.Models.DateValTest
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>DateValTest</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.DateOfBirth, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.DateOfBirth, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.DateOfBirth, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

please show me what to add in unobtrusive js code as a result old dates will not be taken.

如果您使用的是jQuery ui来显示日历,则可以将其MinDate属性设置为0,这样用户就无法选择过去的日期,

$('#datepicker').datepicker({ minDate: 0 });

In order to get client side validation, your attribute must implement IClientValidatable and you need to include scripts to add the rules to the $.validator For more details on implementing client side validation, refer to The complete-guide-to-validation-in-asp.net-mvc-3-part-2 .

You attribute would need to be

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class TodayOrGreater: ValidationAttribute, IClientValidatable
{
    private const string _DefaultErrorMessage = "The {0} value must be greater than or equal to today's date.";
    private DateTime _MinDate;

    public TodayOrGreater()
    {
        ErrorMessage = _DefaultErrorMessage;
        _MinDate = DateTime.Today;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        ....
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "todayorgreater",
        };
        rule.ValidationParameters.Add("mindate", _MinDate);
        yield return rule;
    }
}

and the scripts

$.validator.unobtrusive.adapters.add('todayorgreater', ['mindate'], function (options) {
    options.rules['todayorgreater'] = { mindate: options.params.mindate };
    options.messages['todayorgreater'] = options.message;
});

$.validator.addMethod("todayorgreater", function (value, element, param) {
    var date = new Date(value);
    var minDate = new Date(param.mindate);
    return date >= minDate;
});

Side note: If your wanting to allow todays date, then you want if (_dateJoin >= DateTime.Today) , not if (_dateJoin >= DateTime.Now) . You will probably also want to include a check for a null value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM