C# ASP.NET MVC-验证表单输入
我是ASP.NETMVC新手。我正在尝试验证一些用户输入。我的视图后面的模型如下所示:C# ASP.NET MVC-验证表单输入,c#,asp.net-mvc,C#,Asp.net Mvc,我是ASP.NETMVC新手。我正在尝试验证一些用户输入。我的视图后面的模型如下所示: public class ViewModel { [Required] public int? Minimum { get; set; } [Required] public int? Maximum { get; set; } } public class MyController { public ActionResult Edit(int? id) { var mo
public class ViewModel
{
[Required]
public int? Minimum { get; set; }
[Required]
public int? Maximum { get; set; }
}
public class MyController
{
public ActionResult Edit(int? id)
{
var model = new ViewModel();
return View(model);
}
[HttpPost]
public ActionResult Edit(ViewModel model)
{
if (ModelState.IsValid) {
var result = await model.SaveAsync();
return RedirectToAction("Edit", new { id = result.DemandId, u = "true" });
}
return View(model);
}
}
我的视图(.cshtml文件)如下所示
@model Website.Models.ViewModel
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
...
<div class="row">
<div class="col-sm-6"><input class="form-control input-sm" id="Minimum" name="Minimum" type="text" /></div>
<div class="col-sm-6"><input class="form-control input-sm" id="Maximum" name="Maximum" type="text" /></div>
</div>
...
<br />
<button type="submit" class="btn btn-primary">Save</button>
}
我的代码正在验证是否提供了该字段。但是,我需要添加一些业务规则。例如,我需要确保最大值大于最小值。如果不是,那么我需要给用户一个错误。我打算有更复杂的验证场景
我的问题是,我应该如何在ASP.NET MVC中处理这些高级验证场景?如果需要从IValidatableObject派生类,请阅读这篇有用的文章:
您需要从IValidatableObject派生类,请看这篇有用的文章:
在视图模型中使用
IValidatableObject
界面
public class ViewModel : IValidatableObject
{
[Required]
public int? Minimum { get; set; }
[Required]
public int? Maximum { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var results = new List<ValidationResult>();
if (this.Minimum > this.Maximum)
{
results.Add(new ValidationResult("Maximum must be larger than Minimum"));
}
return results;
}
}
public类ViewModel:IValidatableObject
{
[必需]
公共int?最小值{get;set;}
[必需]
公共int?最大值{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{
var results=新列表();
如果(this.Minimum>this.maxium)
{
结果。添加(新的ValidationResult(“最大值必须大于最小值”);
}
返回结果;
}
}
当视图模型中使用
IValidatableObject
界面时,这将强制ModelState.IsValid
为false
public class ViewModel : IValidatableObject
{
[Required]
public int? Minimum { get; set; }
[Required]
public int? Maximum { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var results = new List<ValidationResult>();
if (this.Minimum > this.Maximum)
{
results.Add(new ValidationResult("Maximum must be larger than Minimum"));
}
return results;
}
}
public类ViewModel:IValidatableObject
{
[必需]
公共int?最小值{get;set;}
[必需]
公共int?最大值{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{
var results=新列表();
如果(this.Minimum>this.maxium)
{
结果。添加(新的ValidationResult(“最大值必须大于最小值”);
}
返回结果;
}
}
这将强制
ModelState.IsValid在Minimum>Maximum
时为false。如果您要进行大量验证,我建议您深入到库中
一旦安装,您需要在Mvc应用程序的应用程序启动事件期间配置FluentValidationModelValidatorProvider
(位于FluentValidation.Mvc
命名空间中)
这使得Fluent验证能够挂接到ModelState
并触发ModelState.IsValid
等
protected void Application_Start() {
/* Your other initializing code */
FluentValidationModelValidatorProvider.Configure();
}
然后创建验证器
public class ViewModelValidator : AbstractValidator<ViewModel> {
public ViewModelValidator() {
RuleFor(x => x.Minimum).NotNull();
RuleFor(x => x.Maximum).NotNull.GreaterThan(x => x.Minimum)
}
}
下面是一个示例,它可以轻松创建自定义的、数据库驱动的验证 如果您要进行大量验证,我建议您深入到库中
一旦安装,您需要在Mvc应用程序的应用程序启动事件期间配置FluentValidationModelValidatorProvider
(位于FluentValidation.Mvc
命名空间中)
这使得Fluent验证能够挂接到ModelState
并触发ModelState.IsValid
等
protected void Application_Start() {
/* Your other initializing code */
FluentValidationModelValidatorProvider.Configure();
}
然后创建验证器
public class ViewModelValidator : AbstractValidator<ViewModel> {
public ViewModelValidator() {
RuleFor(x => x.Minimum).NotNull();
RuleFor(x => x.Maximum).NotNull.GreaterThan(x => x.Minimum)
}
}
下面是一个示例,它可以轻松创建自定义的、数据库驱动的验证 一种方法是有一个方法(在控制器上或一个单独的验证器类上,您将模型提供给它进行验证)
通过这种方式,您可以随心所欲地进行详细的验证(在不污染POCO视图的情况下访问数据库/服务/文件等)
为了简单起见,让我们将其内联到控制器:
[HttpPost]
public ActionResult Edit(ViewModel model)
{
ValidateEditViewModel(model);
if (ModelState.IsValid) {
内部ValidateEditViewModel:
private void ValidateEditViewModel(ViewModel model){
if(model.. // something is wrong)
{
// this sets ModelState.IsValid = false
ModelState.AddModelError("< PropertyNameThatIsInError >", "The item is removed from your cart");
}
}
private void validateEdit视图模型(视图模型模型){
如果(模型..//出现问题)
{
//这将设置ModelState.IsValid=false
AddModelError(“”,“该项目已从购物车中删除”);
}
}
更好的是有一个验证器类,它通过DI注入控制器,然后在整个过程中使用(这是更可测试和可靠的)
我倾向于使用IControllerValidator类(因此,对于Homecontroller,IHomeControllerValidator),该类由Validator(HomeValidator)具体类实现,并根据控制器构造通过unity/dependencyResolver注入
工作得很漂亮
最后一个扩展是有一个基本控制器类,它接受验证器类实例,并将其存储在使用该基类的所有控制器的一致位置
public class BaseController<TValidator> : Controller{
protected TValidator validator;
public BaseController(TValidator validator){
this.validator = validator;
}
}
公共类BaseController:控制器{
受保护的TValidator验证器;
公共BaseController(TValidator验证器){
this.validator=验证程序;
}
}
所以HomeController是
public class HomeController : BaseController<IHomeControllerValidator>
{
public HomeController(IHomeControllerValidator validator) : base(validator)
{
}
}
公共类HomeController:BaseController
{
公共家庭控制器(IHomeControllerValidator验证器):基本(验证器)
{
}
}
HTH一种方法是拥有一个方法(在控制器上或一个单独的验证器类上,您将模型提供给它进行验证)
通过这种方式,您可以随心所欲地进行详细的验证(在不污染POCO视图的情况下访问数据库/服务/文件等)
为了简单起见,让我们将其内联到控制器:
[HttpPost]
public ActionResult Edit(ViewModel model)
{
ValidateEditViewModel(model);
if (ModelState.IsValid) {
内部ValidateEditViewModel:
private void ValidateEditViewModel(ViewModel model){
if(model.. // something is wrong)
{
// this sets ModelState.IsValid = false
ModelState.AddModelError("< PropertyNameThatIsInError >", "The item is removed from your cart");
}
}
private void validateEdit视图模型(视图模型模型){
如果(模型..//出现问题)
{
//这将设置ModelState.IsValid=false
AddModelError(“”,“该项目已从购物车中删除”);
}
}
更好的是有一个验证器类,它通过DI注入控制器,然后在整个过程中使用(这是更可测试和可靠的)
我倾向于使用IControllerValidator类(因此,对于Homecontroller,IHomeControllerValidator),该类由验证器实现