数据类型客户端验证在MVC 2中不起作用

时间:2011-11-22 06:25:46

标签: asp.net-mvc asp.net-mvc-2 date data-annotations client-side-validation

我们有一个名为DateReleased的属性,其中添加了以下Data Annotation属性

[Required]
[DataType(DataType.Date, ErrorMessage = "Please enter date")]
[DisplayName("Date Released")]
public object DateReleased { get; set; }

以下是为将新记录插入数据库而实施的行动

[HttpPost]
public ActionResult Create([Bind(Exclude="Id")] Movie movie)
{
    try
    {
        if (ModelState.IsValid)
        {
            _entities.AddToMovies(movie);
            _entities.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(movie);
    }
    catch
    {
        return View();
    }
}

我已通过在创建视图中放置以下代码行来启用客户端验证

<script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.validate.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftAjax.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftMvcAjax.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftMvcValidation.js"></script>

<% Html.EnableClientValidation(); %>

但我很惊讶地发现只有客户端才会启动必需的验证。 Date的数据类型验证仅在服务器端触发。请让我知道客户端验证失败的原因以及触发客户端验证的解决方法。

2 个答案:

答案 0 :(得分:4)

是。添加自定义属性类,如下所示

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class DateAttribute : DataTypeAttribute
{
    public DateAttribute() : base(DataType.Date) { }

    public override string FormatErrorMessage(string name)
    {
        if (ErrorMessage == null && ErrorMessageResourceName == null)
        {
            ErrorMessage = ValidatorResources.DateAttribute_Invalid;
        }
        return base.FormatErrorMessage(name);
    }

    public override bool IsValid(object value)
    {
        if (value == null) return true;
        DateTime retDate;
        return DateTime.TryParse(Convert.ToString(value), out retDate);
    }
}

创建客户端验证规则类

public class ModelClientValidationDateRule:ModelClientValidationRule
{
    public ModelClientValidationDateRule(string errorMessage)
    {
        ErrorMessage = errorMessage;
        ValidationType = "date";
    }
}

创建一个挂接自定义属性和客户端验证规则的适配器类,如下所示。确保添加上述属性类的引用

public class DateAttributeAdapter : DataAnnotationsModelValidator<DateAttribute>
{
    public DateAttributeAdapter(ModelMetadata metadata, ControllerContext context, DateAttribute attribute)
        : base(metadata, context, attribute) { }

    public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
    {
        return new[] { new ModelClientValidationDateRule(ErrorMessage) };
    }
}

然后修改global.asax文件

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterRoutes(RouteTable.Routes);

    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(DateAttribute), typeof(DateAttributeAdapter));
}

将属性添加到模型类中,如下所示

[Date]
public object DateReleased { get; set; }

在视图中添加以下客户端代码

<script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.validate.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftAjax.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftMvcAjax.js"></script>
<script type="text/javascript" src="../../Scripts/MicrosoftMvcValidation.js"></script>
<script type="text/javascript">

Sys.Mvc.ValidatorRegistry.validators["date"] = function (rule) {
    // initialization code can go here.
    return function (value, context) {
        if (value.length > 0) {
            var d = new Date(value);
            if (!isNaN(d))
                return true;
            return rule.ErrorMessage;
        }
        else {
            return true;
        }
    };
};

希望这会对你有所帮助。

答案 1 :(得分:3)

DataTypeAttribute不进行验证。它实际上仅用于选择Editor / DisplayTemplates(因此控制数据的格式化方式),也用于通用模板中的格式选择。

我不确定为什么你认为这会做任何类型的验证,但事实并非如此。控制验证是什么实际数据类型。由于您将数据项创建为object,因此无法对日期格式进行任何更新。相反,让您的属性键入DateTime?或可以为空的