提问人:Eduardo 提问时间:6/18/2011 更新时间:6/19/2011 访问量:908
ASP.NET MVC 3 - 选择每个提交按钮验证的模型属性
ASP.NET MVC 3 - Choose which model property each submit button validates
问:
我有一个带有三个提交按钮的视图。第一个按钮必须验证某些字段,第二个按钮必须验证其他字段,第三个按钮不验证任何内容。 如何在客户端(不显眼)和服务器端执行此操作?
答:
最有可能的是大量手工卷制的使用,特别是如果您希望它不显眼。您将需要创建类似的东西,然后在单击操作上,您的 javascript 代码将验证您想要的内容。我想jQuery Verify有某种类型的规则集支持,但你必须弄清楚这一点。<input data-validationgroup="group1"...
您必须在服务器端执行类似的序列,并创建规则集类型验证类/块/方法,以便将提交操作解释为相关规则集。对于这部分,我会查看像 FluentValidation 这样的库。
要实现您想要的东西,您极不可能使用模型类上的 DataAnnotations 属性来实现这一点。
评论
就我个人而言,我一直喜欢并在我的所有项目中使用 FluentValidation.NET 库。不仅在表达验证规则方面非常强大,而且该库与 ASP.NET MVC 具有出色的集成。因此,我将尝试使用它为此问题提供一个示例解决方案(目前仅服务器端验证,如果您愿意,稍后我们可以讨论不显眼的客户端验证)。
因此,使用默认模板启动一个新的 ASP.NET MVC 3 项目并安装 NuGet 包(当前稳定版本为 2.0.0.0)。FluentValidation.MVC3
然后,让我们定义一个视图模型:
public class MyViewModel
{
public string Field1 { get; set; }
public string Field2 { get; set; }
}
现在我们可以假设 if is clicked 是必需的,if is clicked 是必需的,if is click 是必需的,if is click 它们都不是必需的。一个虚构的场景,但非常接近您的要求。button1
Field1
button2
Field2
button3
现在,让我们为这个模型定义两个不同的 Fluent 验证器,分别对应于 和 :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" />
}
评论