编写自定义验证属性非常容易:
public class RequiredIfPropertyIsEmptyAttribute : RequiredAttribute
{
private readonly string _otherProperty;
public RequiredIfPropertyIsEmptyAttribute(string otherProperty)
{
_otherProperty = otherProperty;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(_otherProperty);
if (property == null)
{
return new ValidationResult(string.Format("Unknown property {0}", _otherProperty));
}
var otherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);
if (otherPropertyValue == null)
{
return base.IsValid(value, validationContext);
}
return null;
}
}
那么你可以有一个视图模型:
public class MyViewModel
{
public string Foo { get; set; }
[RequiredIfPropertyIsEmpty("Foo")]
public string SelectedItemId { get; set; }
public IEnumerable<SelectListItem> Items {
get
{
return new[]
{
new SelectListItem { Value = "1", Text = "item 1" },
new SelectListItem { Value = "2", Text = "item 2" },
new SelectListItem { Value = "3", Text = "item 3" },
};
}
}
}
控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new MyViewModel());
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
当然还有观点:
@model MyViewModel
@using (Html.BeginForm())
{
<div>
@Html.LabelFor(x => x.Foo)
@Html.EditorFor(x => x.Foo)
</div>
<div>
@Html.LabelFor(x => x.SelectedItemId)
@Html.DropDownListFor(x => x.SelectedItemId, Model.Items, "-- select an item --")
@Html.ValidationMessageFor(x => x.SelectedItemId)
</div>
<input type="submit" value="OK" />
}
或者你可以像我一样做:下载并使用FluentValidation.NET library,忘记数据注释并编写以下验证逻辑,这看起来很不言自明:
public class MyViewModelValidator: AbstractValidator<MyViewModel>
{
public MyViewModelValidator()
{
RuleFor(x => x.SelectedItemId)
.NotEmpty()
.When(x => !string.IsNullOrEmpty(x.Foo));
}
}
请继续Install-Package FluentValidation.MVC3,让您的生活更轻松。