总之,方法是创建
- 所有视图模型支持验证的警告类型的自定义数据注释属性;
- 视图模型将继承的已知基类;
- 我们必须在JavaScript中为每个自定义属性复制逻辑。
请注意,下面的代码只是说明了方法,我不得不承担很多事情而不知道完整的上下文。
视图模型
在这种情况下,最好视图模型从实际模型,它是一个好主意,反正分开。一种可能的方法是有支持的警告所有视图模型基类:
public abstract class BaseViewModel
{
public bool IgnoreWarnings { get; set; }
}
一个模型需要单独的关键原因是,有一个在存储在数据库中的IgnoreWarnings
性能没有多大意义。
派生的视图模型,然后将如下所示:
public class YourViewModel : BaseViewModel
{
[Required]
[StringLengthWarning(MaximumLength = 5, ErrorMessage = "Your Warning Message")]
public string YourProperty { get; set; }
}
StringLengthWarning
是服务器和客户端验证自定义数据注解属性。它只支持最大长度,并且可以很容易地用任何其他必要的属性进行扩展。
数据注释属性
属性的核心是IsValid(value, validationContext
方法。
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class StringLengthWarningAttribute : ValidationAttribute, IClientValidatable
{
public int MaximumLength { get; set; }
public override bool IsValid(object value)
{
return true;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var model = validationContext.ObjectInstance as BaseViewModel;
var str = value as string;
if (!model.IgnoreWarnings && (string.IsNullOrWhiteSpace(str) || str.Length > MaximumLength))
return new ValidationResult(ErrorMessage);
return base.IsValid(value, validationContext);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
yield return new StringLengthWarningValidationRule(MaximumLength, ErrorMessage);
}
}
属性实现IClientValidatable
并利用自定义客户端验证规则:
public class StringLengthWarningValidationRule : ModelClientValidationRule
{
public StringLengthWarningValidationRule(int maximumLength, string errorMessage)
{
ErrorMessage = errorMessage;
ValidationType = "stringlengthwarning";
ValidationParameters.Add("maximumlength", maximumLength);
ValidationParameters.Add("ignorewarningsfield", "IgnoreWarnings");
}
}
客户端JavaScript
最后,要使其工作,你需要下面的JavaScript从您的角度引用:
$(function() {
$.validator.addMethod('stringlengthwarning', function (value, element, params) {
var maximumlength = params['maximumlength'];
var ignorewarningsfield = params['ignorewarningsfield'];
var ctl = $("#" + ignorewarningsfield);
if (ctl == null || ctl.is(':checked'))
return true;
return value.length <= maximumlength;
});
$.validator.unobtrusive.adapters.add("stringlengthwarning", ["maximumlength", "ignorewarningsfield"], function (options) {
var value = {
maximumlength: options.params.maximumlength,
ignorewarningsfield: options.params.ignorewarningsfield
};
options.rules["stringlengthwarning"] = value;
if (options.message) {
options.messages["stringlengthwarning"] = options.message;
}
});
}(jQuery));
JavaScript提供了一些您可能想要重新访问的假设(复选框名称等)。
UPDATE:HTML辅助
要为错误和警告分别显示的验证消息,一对夫妇的助手将是必要的。下面的类提供了一个示例:
public static class MessageHelpers
{
public static MvcHtmlString WarningMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] != null)
return htmlHelper.ValidationMessageFor(expression);
return MvcHtmlString.Empty;
}
public static MvcHtmlString ErrorMessageFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
if (htmlHelper.ViewData.ModelState["IgnoreWarnings"] == null)
return htmlHelper.ValidationMessageFor(expression);
return MvcHtmlString.Empty;
}
}
在他们可以照常使用的观点:
@Html.EditorFor(model => model.YourProperty)
@Html.ErrorMessageFor(model => model.YourProperty)
@Html.WarningMessageFor(model => model.YourProperty)
我假设你想要像'[WarningOnFieldLength(150)]'这样的属性? –
@TiesonT。对,就是这样。 – Alex
像这样的答案可以让你在那里:http://stackoverflow.com/a/9652582/534109 - 假设你想使用强类型助手,该属性可以用来为扩展生成一个钩子。我会看看我是否可以一起刮出一个真正的答案... –