gpt4 book ai didi

c# - 仅限时间的编辑器模板和验证

转载 作者:行者123 更新时间:2023-11-30 23:09:22 24 4
gpt4 key购买 nike

在创建具有不显眼验证的仅时间输入字段时遇到一些问题,映射到不可为 null 的 DateTime 字段。

我正在使用数据库优先的方法。数据库具有用于存储日期和时间的日期时间字段。我的意思是,一些日期时间具有真实日期数据和 00:00:00 时间,而其他日期时间具有无意义的实时日期数据。我知道这是由于 EF5 和 C# 数据类型的限制造成的。现在使用EF6,但不是特别打算换数据库。

这是 View 模型

[UIHint("Date")]
public DateTime MatchDate { get; set; }

[UIHint("Time")]
public DateTime StartTime { get; set; }

仅日期字段 MatchDate 正在运行。它使用 EditorFor 模板 Date.cshtml(如下)。它允许文本输入,正确附加 jQuery 日期选择器并正确验证服务器端和客户端,且不显眼。

@model DateTime
@if (Model == DateTime.MinValue)
{
@Html.TextBox("", "", new { @class = "datepicker" })
}
else
{
@Html.TextBox("", String.Format("{0:d/M/yyyy}", Model), new { @class = "datepicker" })
}

所以我为 Time.cshtml 创建了一个新的 EditorFor 模板

@model DateTime
@if (Model == DateTime.MinValue)
{
@Html.TextBox("", "", new { @class = "timepicker" })
}
else
{
@Html.TextBox("", String.Format("{0:h\\:mm tt}", Model), new { @class = "timepicker" })
}

此时 Html 输入元素获得不需要的 data-val-date 属性,导致不显眼的 date 验证。我发现通过添加 [DataType(DataType.Time)],不再添加 data-val-date。虽然这是一件好事,但我不确定这是否正是(而且只是)数据类型属性应该做的事情。所以这是问题的第一部分。

接下来,我为 12 小时时间格式创建了自定义验证规则(服务器端和客户端)。

注释:

public class TimeTwelveAttribute : ValidationAttribute, IClientValidatable
{
private const string _ErrorMessage = "Invalid time format. Please use h:mm am/pm (TimeAttribute)";
public TimeTwelveAttribute()
{
this.ErrorMessage = _ErrorMessage;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = _ErrorMessage,
ValidationType = "timetwelve"
};
}

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
DateTime time;
if (value == null || !DateTime.TryParse(value.ToString(), out time))
{
return new ValidationResult(_ErrorMessage);
}

return ValidationResult.Success;
}
}

JavaScript

$.validator.unobtrusive.adapters.addSingleVal("timetwelve");
$.validator.addMethod(
"timetwelve",
function (value, element) {
return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(value);
},
"Invalid time format. Please use h:mm am/pm"
);

但是,在 StartTime 中添加 [TimeTwelve] 数据注释没有任何效果:

  • 服务器端验证正在进行,但它创建了一条我无法覆盖的不同错误消息:“值‘asdf’对于开始时间无效。”
  • 如果我在时间字段中键入“asdf”,则不会弹出客户端验证消息。

我认为这是由映射到 C# DateTimes 的回发值引起的。无论采用何种机制,它都具有更高的优先级并覆盖所有其他验证。作为练习,我将 StartTime 重写为字符串(并更新了模板等),果然 [TimeTwelve] 正常工作,客户端和服务器端都如预期的那样工作。我觉得这个方面在 stackoverflow 上的任何相关问题中都没有涉及。

所以我的问题的第二部分,假设我真的更喜欢在我的 View 模型中使用 DateTimes,我怎样才能让验证工作?

This是我能找到的最接近的问题,但是是从 2013 年开始的。

最佳答案

首先,要让您的客户端验证正常工作,请将您的脚本更改为

$.validator.unobtrusive.adapters.add('timetwelve', function (options) {
options.rules['timetwelve'] = {};
options.messages['timetwelve'] = options.message;
});
// no need to hard code the message - it will use the one you have defined in the validation atribute
$.validator.addMethod('timetwelve', function (value, element) {
return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(value);
});

或者你可以使用.addBool()方法

$.validator.unobtrusive.adapters.addBool("timetwelve");

至于接收 The value 'asdf' is not valid for Start Time 如果您在文本框中输入“asdf”,这是默认行为。 DefaultModelBinder 使用 ValueConverters 将 Request 中的值解析为属性类型。由于 asdf 无法转换为 DateTime,因此添加了一个 ModelState 错误并且没有进行进一步的验证(因为它已经无效并且不会观点)。当然,一旦客户端验证开始工作,您将永远不会到达那个点(除非用户已禁用 javascript 或其恶意用户)。

另请注意,您的 IsValid() 方法可以简单地是

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return ValidationResult.Success;
}

当您到达此处时,DefaultModelBinder 已经设置了 DateTime 值(通过将今天的日期与在表单中输入的时间相结合),因此没有需要再次尝试解析。

关于c# - 仅限时间的编辑器模板和验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45853482/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com