自定义ValidationAttribute不触发视图模型中的IsValid函数调用
本文关键字:IsValid 函数调用 模型 视图 ValidationAttribute 自定义 | 更新日期: 2023-09-27 18:10:44
我已经创建了自己的自定义ValidationAttribute
:
public class UrlValidationAttribute : ValidationAttribute
{
public UrlValidationAttribute() {}
public override bool IsValid(object value)
{
if (value == null)
return true;
var text = value as string;
Uri uri;
return (!string.IsNullOrWhiteSpace(text) &&
Uri.TryCreate(text, UriKind.Absolute, out uri));
}
}
我正在我的一个模型上使用它,它工作得很好。然而,现在我正试图在视图模型上使用它:
public class DeviceAttribute
{
public DeviceAttribute(int id, attributeDefinition, String url)
{
ID = id;
Url = url;
}
public int ID { get; set; }
[UrlValidation]
public String Url { get; set; }
}
视图模型在部分视图中使用如下:
@model List<ICMDB.Models.DeviceAttribute>
<table class="editor-table">
@foreach (var attribute in Model)
{
<tr>
@Html.HiddenFor(a => attribute.ID)
<td class="editor-label">
@Html.LabelFor(a => attribute.Url)
</td>
<td class="editor-field">
@Html.TextBoxFor(a => attribute.Url)
@Html.ValidationMessageFor(a => attribute.Url)
</td>
</tr>
}
</table>
由于某些未知的原因,当UrlValidationAttribute的构造函数被触发时,IsValid函数没有被触发。什么好主意吗?
编辑:在进一步的调查中,似乎这正在发生,因为DeviceAttribute
视图模型实际上是一个部分的视图模型。整个页面传递一个不同的视图模型,其中包含DeviceAttribute
视图模型的列表。因此,当我的控制器操作被调用时,完整的页面视图模型被构造并填充其值,但没有DeviceAttribute
视图模型被构造,因此为什么没有验证运行。
我建议您使用编辑器模板而不是编写foreach循环。我想你的主视图模型看起来像这样:
public class MyViewModel
{
public List<DeviceAttribute> Devices { get; set; }
...
}
现在在主视图中:
@model MyViewModel
@using (Html.BeginForm())
{
<table class="editor-table">
@Html.EditorFor(x => x.Devices)
</table>
<input type="submit" value="OK" />
}
,在相应的编辑器模板(~/Views/Shared/EditorTemplates/DeviceAttribute.cshtml
)中:
@model DeviceAttribute
<tr>
@Html.HiddenFor(x => x.ID)
<td class="editor-label">
@Html.LabelFor(x => x.Url)
</td>
<td class="editor-field">
@Html.TextBoxFor(x => x.Url)
@Html.ValidationMessageFor(x => x.Url)
</td>
</tr>
POST操作将视图模型收回:
[HttpPost]
public ActionResult Index(MyViewModel model)
{
...
}
现在,默认的模型绑定器将成功地绑定视图模型中的所有值并启动验证。