Виконайте перевірку на стороні клієнта для спеціального атрибута


74

Я створив спеціальний атрибут перевірки:

public class FutureDateAttribute : ValidationAttribute
    {
        public override bool IsValid(object value) 
        {
            if (value == null|| (DateTime)value < DateTime.Now)
                return false;

            return true;
        }

    }

Як я можу змусити це працювати на стороні клієнта також за допомогою jquery?

Відповіді:


165

Ось як далі:

Почніть з визначення власного атрибута перевірки:

public class FutureDateAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        if (value == null || (DateTime)value < DateTime.Now)
            return false;

        return true;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "futuredate"
        };
    }
}

Зверніть увагу, як він реалізує IClientValidatable . Далі ми пишемо нашу модель:

public class MyViewModel
{
    [FutureDate(ErrorMessage = "Should be in the future")]
    public DateTime Date { get; set; }
}

Потім контролер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            // intentionally put in the past
            Date = DateTime.Now.AddDays(-1)
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

і нарешті вид:

@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.Date)
    @Html.TextBoxFor(x => x.Date)
    @Html.ValidationMessageFor(x => x.Date)
    <input type="submit" value="OK" />
}

Останньою частиною чарівництва є визначення користувацького адаптера:

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    // we add a custom jquery validation method
    jQuery.validator.addMethod('greaterThan', function (value, element, params) {
        if (!/Invalid|NaN/.test(new Date(value))) {
            return new Date(value) > new Date($(params).val());
        }
        return isNaN(value) && isNaN($(params).val()) || (parseFloat(value) > parseFloat($(params).val()));
    }, '');

    // and an unobtrusive adapter
    jQuery.validator.unobtrusive.adapters.add('futuredate', { }, function (options) {
        options.rules['greaterThan'] = true;
        options.messages['greaterThan'] = options.message;
    });
</script>

1
@raklos, що залежатиме від налаштувань локалізації браузера та сервера. Якщо у вас є відмінності, все ускладнюється, оскільки один формат може пройти перевірку клієнта, але не перевірку сервера, і навпаки. Також вам вирішувати, в якому форматі ви хочете, щоб були ваші дати.
Дарін Димитров

аааа, я міг би вас за це поцілувати
Шашанк Шехар

2
чудовий приклад. Щоб змусити клієнта працювати для мене, адаптеру потрібно було змінити його return new Date(value) > new Date($(params).val()); на return new Date(value) > new Date();. new Date ($ (params) .val ()) to new Date ()
PhilW

У мене виникла проблема з тим, щоб сторона клієнта працювала за допомогою Ajax.BeginForm замість Html.BeginForm. Чи буде проблема в цьому сценарії?
user1790300

1
@kehrk, так, якщо ви використовуєте набори ASP.NET 4, найкраще зробити його частиною якогось набору.
Дарін Димитров

5

Минуло трохи часу з моменту того, як було задано ваше запитання, але якщо ви все ще любите метадані, і ви все ще відкриті для спрощених альтернатив, ви можете вирішити свою проблему, використовуючи такі анотації:

[Required]
[AssertThat("Date > Now()")]
public DateTime? Date { get; set; }

Це працює як для сервера, так і для клієнта, нестандартно. Детальніше див. У бібліотеці ExpressiveAnnotations .


Ти врятував мій день своєю бібліотекою. Такий простий у використанні та дуже корисний. Подяка
Maco
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.