Лично мне всегда нравилась и использовалась библиотека FluentValidation.NET во всех моих проектах.Мало того, что он очень мощный с точки зрения выражения правил проверки, но эта библиотека имеет отличную интеграцию с ASP.NET MVC.Поэтому я попытаюсь предоставить пример решения этой проблемы, используя его (пока только проверка на стороне сервера, позже мы можем поговорить о ненавязчивой проверке на стороне клиента, если хотите).
Итак, запустите новый ASP.NETПроект MVC 3 с использованием шаблона по умолчанию и установка пакета FluentValidation.MVC3
NuGet (текущая стабильная версия 2.0.0.0).
Затем давайте определим модель представления:
public class MyViewModel
{
public string Field1 { get; set; }
public string Field2 { get; set; }
}
Теперь мыМожно предположить, что при нажатии button1
требуется Field1
, а при нажатии button2
требуется Field2
, а при нажатии button3
ничего из них не требуется.Вымышленный сценарий, но довольно близкий к вашим требованиям.
Теперь давайте определим два разных беглых валидатора для этой модели, соответствующих каждому button1
и button2
:
public class MyModelValidator1 : AbstractValidator<MyViewModel>
{
public MyModelValidator1()
{
RuleFor(x => x.Field1)
.NotEmpty();
}
}
public class MyModelValidator2 : AbstractValidator<MyViewModel>
{
public MyModelValidator2()
{
RuleFor(x => x.Field2)
.NotEmpty();
}
}
Теперь, потому что этотолько во время выполнения мы знаем, какая кнопка нажата, нам нужно применить правильный валидатор на основе значения в запросе.Итак, давайте напишем собственную фабрику поставщиков валидаторов:
public class MyFactory : IValidatorFactory
{
private readonly Func<HttpContextBase> _contextProvider;
public MyFactory(Func<HttpContextBase> contextProvider)
{
_contextProvider = contextProvider;
}
public IValidator GetValidator(Type type)
{
if (type == typeof(MyViewModel))
{
var context = _contextProvider();
if (!string.IsNullOrEmpty(context.Request["button1"]))
{
return new MyModelValidator1();
}
if (!string.IsNullOrEmpty(context.Request["button2"]))
{
return new MyModelValidator2();
}
}
return null;
}
public IValidator<T> GetValidator<T>()
{
return (IValidator<T>)GetValidator(typeof(T));
}
}
и зарегистрируем ее в Application_Start
:
ModelValidatorProviders.Providers.Add(
new FluentValidationModelValidatorProvider(
new MyFactory(() => new HttpContextWrapper(HttpContext.Current))
)
);
, и это почти все.Теперь то, что осталось, тривиально.
Контроллер:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
return Content("Thanks for submitting", "text/plain");
}
}
и вид:
@model MyViewModel
@using (Html.BeginForm())
{
<div>
@Html.LabelFor(x => x.Field1)
@Html.EditorFor(x => x.Field1)
@Html.ValidationMessageFor(x => x.Field1)
</div>
<div>
@Html.LabelFor(x => x.Field2)
@Html.EditorFor(x => x.Field2)
@Html.ValidationMessageFor(x => x.Field2)
</div>
<input type="submit" value="Submit with button 1" name="button1" />
<input type="submit" value="Submit with button 2" name="button2" />
<input type="submit" value="Submit with button 3" name="button3" />
}