MVC 自定义验证工作但未显示错误

gil*_*rpa 3 c# validation asp.net-mvc asp.net-mvc-4

我在 MVC 版本 5 中遇到自定义验证问题。

我有下面的代码作为验证器。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace PortalWebsite.Common
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class GreaterThanAttribute : ValidationAttribute, IClientValidatable
    {
        public string OtherPropertyName { get; private set; }
        public bool AllowEquality { get; private set; }

        public GreaterThanAttribute(string otherPropertyName, bool allowEquality = true)
        {
            AllowEquality = allowEquality;
            OtherPropertyName = otherPropertyName;
        }


        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var result = ValidationResult.Success;
            var otherValue = validationContext.ObjectType.GetProperty(OtherPropertyName)
                .GetValue(validationContext.ObjectInstance, null);
            if (value != null)
            {
                if (value is DateTime)
                {

                    if (otherValue != null)
                    {
                        if (otherValue is DateTime)
                        {
                            if (!OtherPropertyName.ToLower().Contains("DateTo"))
                            {
                                if ((DateTime)value > (DateTime)otherValue)
                                {
                                    result = new ValidationResult(ErrorMessage);
                                }
                            }
                            else
                            {
                                if ((DateTime)value < (DateTime)otherValue)
                                {
                                    result = new ValidationResult(ErrorMessage);
                                }
                            }
                            if ((DateTime)value == (DateTime)otherValue && !AllowEquality)
                            {
                                result = new ValidationResult(ErrorMessage);
                            }
                        }
                    }
                }
            }
            return result;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = ErrorMessage,
                ValidationType = "comparedates"
            };
            rule.ValidationParameters["otherpropertyname"] = OtherPropertyName;
            rule.ValidationParameters["allowequality"] = AllowEquality ? "true" : "";
            yield return rule;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在我的视图模型中,我有:

public int Id { get; set; }
public DateTime? NotificationDateTo { get; set; }
[Display(Name = "Notification Date")]
[GreaterThan("NotificationDateTo", ErrorMessage = "Start date cannot be before end date")]
public DateTime? NotificationDateFrom { get; set; }
Run Code Online (Sandbox Code Playgroud)

此代码正在运行,并且 IsValid 的结果已正确设置。我的问题是代码没有返回到调用视图。它只是继续下去,好像没有什么是无效的。

我的看法是这样的(略):

@using (Html.BeginForm("SearchResults", "Claims", new { id = 1 }, FormMethod.Get))
{
<div class="row">
    <div class="large-12 columns">
        <div class="row">
            <div class="small-3 columns">
                @Html.LabelFor(m => m.NotificationDateFrom, new { @class = "right inline" })
            </div>
            <div class="small-4 columns">
                @Html.TextBoxFor(model => model.NotificationDateFrom, new { autocomplete = "off", @class = "datePicker" })
                <span class="error">@Html.ValidationMessageFor(m => m.NotificationDateFrom)</span>
            </div>
            <div class="small-1 columns">
             and
            </div>
            <div class="small-4 columns">
                @Html.TextBoxFor(model => model.NotificationDateTo, new { autocomplete = "off", @class = "datePicker" })
                <span class="error">@Html.ValidationMessageFor(m => m.NotificationDateTo)</span>
            </div>
        </div>
    </div>
</div>
}
Run Code Online (Sandbox Code Playgroud)

小智 5

在 POST 方法中,您需要检查属性ModelState.IsValid,如果无效,则返回将显示错误消息的视图

public ActionResult SearchResults(yourViewModel model)
{
  if (!ModelState.IsValid)
  {
    return View(model);
  }
  // save and redirect
Run Code Online (Sandbox Code Playgroud)

旁注:除非禁用客户端验证,否则您不应该点击 POST 方法,这表明您尚未包含与GreaterThanAttribute. 您需要包含 2 个将规则添加到验证器的脚本

$.validator.addMethod(...) {
Run Code Online (Sandbox Code Playgroud)

$.validator.unobtrusive.adapters.add(...) {
Run Code Online (Sandbox Code Playgroud)

除非包含这些,否则IClientValidatable在您的属性中实现没有什么意义