【问题标题】:Data type client side validation not working in MVC 2数据类型客户端验证在 MVC 2 中不起作用
【发布时间】:2011-11-22 06:25:46
【问题描述】:

我们有一个名为 DateReleased 的属性,为其添加了以下数据注释属性

[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 的数据类型验证仅在服务器端触发。请让我知道客户端验证失败的原因以及触发客户端验证的解决方法。

【问题讨论】:

  • 如果你真的需要大量的客户端验证,我建议你升级到 MVC3,它有更好的基于 jquery.validate 的验证。在我看来,它不那么麻烦了。

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


【解决方案1】:

是的。添加如下自定义属性类

[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;
        }
    };
};

希望这会对你有所帮助。

【讨论】:

    【解决方案2】:

    DataTypeAttribute 不进行验证。它实际上只用于选择编辑器/显示模板(从而控制数据的格式),也用于通用模板中的格式选择。

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

    【讨论】:

    • 我已将这些属性重新定义为由 ADO.Net 实体框架生成的分部类。我什至用 DateTime 替换了该对象,但验证不起作用。我需要在客户端进行有效日期验证。
    • @suryakiran - 如果您的属性类型是 DateTime?,它将验证它的日期格式是否有效,但对于您的目的而言,它不是有效的日期。如果您需要验证日期是否在某个范围内,则必须编写自己的属性。此外,您将需要编写自定义日期验证 javascript 以使用客户端验证。见haacked.com/archive/2009/11/19/…
    猜你喜欢
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 2011-01-29
    • 2011-12-19
    • 2013-01-09
    • 2014-03-25
    • 2014-08-02
    相关资源
    最近更新 更多