or
using System;using System.ComponentModel.DataAnnotations;namespace PosPayAndBankRec.Models.Validators{ public class Date { public enum ValidationType { RangeValidation, Compare } public class DateValidationAttribute : ValidationAttribute { private ValidationType _validationType; private DateTime? _fromDate; private DateTime _toDate; private string _defaultErrorMessage; private string _propertyNameToCompare; public DateValidationAttribute(string message, string compareWith = "") { _propertyNameToCompare = compareWith; _defaultErrorMessage = message; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var baseProperyInfo = validationContext.ObjectType.GetProperty(_propertyNameToCompare); DateTime startDate; bool NotValid = false; if (baseProperyInfo.GetValue(validationContext.ObjectInstance, null) is DateTime) { startDate = (DateTime)baseProperyInfo.GetValue(validationContext.ObjectInstance, null); if (value != null) { DateTime thisDate = (DateTime)value; if (thisDate <= startDate) { NotValid = true; } } else if (value == null) { //From date as a value but not the to date NotValid = false; } } else { //To date not a date and we have a from date if (value != null) { NotValid = true; } } //return validation result if (NotValid == false) { return null; } else if (NotValid == true) { string message = string.Format(_defaultErrorMessage, validationContext.DisplayName);//, displayAttr.Name); return new ValidationResult(message); } return null; } } }}[Date.DateValidation("Deactivation Date should be greater than the Activation Date.", compareWith: "brActivationDate")]public Nullable<System.DateTime> brDeactivationDate { get; set; } <td> @Html.EditorFor(model => model.brActivationDate) @Html.ValidationMessageFor(model => model.brActivationDate) </td> <td> @Html.EditorFor(model => model.brDeactivationDate) @Html.ValidationMessageFor(model => model.brDeactivationDate) </td>
var companyId = parseInt(@ViewBag.CompanyID);var dataSource = new kendo.data.DataSource({ type: 'aspnetmvc-ajax', transport: { create: { url: '@Url.Action("CreateHost", "Security", new { area = "" })', dataType: 'json' }, read: { url: '@Url.Action("GetHosts", "Security", new { area = "" })', data: { companyId: companyId }, dataType: 'json', type: 'GET' }, update: { url: '@Url.Action("UpdateHost", "Security", new { area = "" })', dataType: 'json' }, destroy: { url: '@Url.Action("DeleteHost", "Security", new { area = "" })', dataType: 'json' } }, schema: { model: { id: 'HostID', fields: { HostID: { type: 'number', editable: false }, StartIP: { type: 'string', editable: true, validation: { required: { message: 'Start IP is required' }, validIP: function (input1) { input1.attr('data-validIP-msg', 'Invalid IP address'); return ipRegEx.test(input1.val()); }, validIPRange: function (input1) { if (input1.is('input[id=StartIP]')) { input1.attr('data-validIPRange-msg', 'Start IP must be smaller than End IP'); var input2 = input1.closest('input[id=EndIP]'); var d1 = input1.val().split('.'); var d2 = input2.val().split('.'); var n1 = ((((((+d1[0]) * 256) + (+d1[1])) * 256) + (+d1[2])) * 256) + (+d1[3]); var n2 = ((((((+d2[0]) * 256) + (+d2[1])) * 256) + (+d2[2])) * 256) + (+d2[3]); return n1 >= n2; } return true; } } }, EndIP: { type: 'string', editable: true, validation: { required: { message: 'End IP is required' }, validIP: function (input2) { input2.attr('data-validIP-msg', 'Invalid IP address'); return ipRegEx.test(input2.val()); }, validIPRange: function (input2) { if (input2.is('input[id=EndIP]')) { input2.attr('data-validIPRange-msg', 'End IP must be greater than Start IP'); var input1 = input2.closest('input[id=StartIP]'); var d1 = input1.val().split('.'); var d2 = input2.val().split('.'); var n1 = ((((((+d1[0]) * 256) + (+d1[1])) * 256) + (+d1[2])) * 256) + (+d1[3]); var n2 = ((((((+d2[0]) * 256) + (+d2[1])) * 256) + (+d2[2])) * 256) + (+d2[3]); return n1 >= n2; } return true; } } }, StatusID: { type: 'number', editable: false, defaultValue: 3 }, CreatedOn: { type: 'date', editable: false, defaultValue: new Date() } } }, data: 'Data', total: 'Total' }, batch: false, pageSize: 30, serverPaging: true, serverFiltering: true, serverSorting: true});var grid = $('#HostsGrid').kendoGrid({ dataSource: dataSource, toolbar: ['create'], columns: [ { field: 'StatusID', title: 'Status', editable: false, filterable: false, sortable: true, template: '#= formatStatus(StatusID, true, "html") #', width: 97 }, { field: 'StartIP', title: 'Start IP', editable: true, filterable: false, sortable: false }, { field: 'EndIP', title: 'End IP', editable: true, filterable: false, sortable: false }, { field: 'CreatedOn', title: 'Added On', editable: false, filterable: true, sortable: true, format: '{0:MM/dd/yyyy hh:mm tt}', width: 150 }, { command: ["edit", "destroy"], title: ' ', width: 200 }, ], columnMenu: true, editable: 'inline', height: 250, filterable: true, pageable: { // Disable traditional paging, we are using virtual scrolling (which does the paging) previousNext: false, numeric: false, // Show the refresh button in the pager refresh: true }, scrollable: { virtual: true }, sortable: true });$("#chartDetails").kendoChart({ chartArea: { margin: 0, height: 550 }, theme: $(document).data("kendoSkin") || "BlueOpal", dataSource: kendoDataSource, title: { text: chartChangesTitle }, legend: { visible: false, position: "bottom" }, seriesDefaults: { labels: { template: "#= kendo.format('{0} - {1:P}', category, percentage)#", visible: true }, stacked: false }, series:[ { type: "pie", field: "InitialVolume", categoryField: "AttributeValue", name: "Initial" }, { type: "pie", field: "ProposedVolume", categoryField: "AttributeValue", name: "Proposed" } ], categoryAxis: { field: "AttributeValue" }, tooltip: { visible: true, template: "#= kendo.format('{0} - {1:P}', category, percentage)#" } });