我创建了自己的自定义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
视图模型,因此不会运行验证。
答案 0 :(得分:-1)
我建议您使用编辑器模板而不是编写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)
{
...
}
现在,默认模型绑定器将成功绑定视图模型中的所有值并启动验证。
这是关于模板的nice blog post。