如何使用属性手动验证模型?

我有一个名为 User的类和一个属性 Name

public class User
{
[Required]
public string Name { get; set; }
}

我想验证它,如果有任何错误添加到控制器的 ModelState或实例化另一个模型状态..。

[HttpPost]
public ActionResult NewUser(UserViewModel userVM)
{
User u = new User();
u.Name = null;


/* something */


// assume userVM is valid
// I want the following to be false because `user.Name` is null
if (ModelState.IsValid)
{
TempData["NewUserCreated"] = "New user created sucessfully";


return RedirectToAction("Index");
}


return View();
}

这些属性适用于 UserViewModel,但是我想知道如何在不将类发送到操作的情况下验证类。

我怎么才能做到呢?

64636 次浏览

您可以使用 验证器来实现这一点。

var context = new ValidationContext(u, serviceProvider: null, items: null);
var validationResults = new List<ValidationResult>();


bool isValid = Validator.TryValidateObject(u, context, validationResults, true);

我在堆栈溢出文档中做了一个条目来解释如何做到这一点:

验证环境

任何验证都需要一个上下文来提供有关正在验证的内容的信息。这可以包括各种信息,例如要验证的对象、一些属性、要在错误消息中显示的名称等。

ValidationContext vc = new ValidationContext(objectToValidate); // The simplest form of validation context. It contains only a reference to the object being validated.

一旦创建了上下文,就有多种方法进行验证。

验证对象及其所有属性

ICollection<ValidationResult> results = new List<ValidationResult>(); // Will contain the results of the validation
bool isValid = Validator.TryValidateObject(objectToValidate, vc, results, true); // Validates the object and its properties using the previously created context.
// The variable isValid will be true if everything is valid
// The results variable contains the results of the validation

验证对象的属性

ICollection<ValidationResult> results = new List<ValidationResult>(); // Will contain the results of the validation
bool isValid = Validator.TryValidatePropery(objectToValidate.PropertyToValidate, vc, results, true); // Validates the property using the previously created context.
// The variable isValid will be true if everything is valid
// The results variable contains the results of the validation

还有更多

有关手动验证的详细信息,请参阅:

因为这个问题是特别关于 ASP.NET MVC 的,所以您可以在 Controller操作中使用 TryValidateObject

所需的方法重载为 TryValidateModel(Object)

验证指定的模型实例。

如果模型验证成功,则返回 true; 否则为 false。

你修改过的源代码

[HttpPost]
public ActionResult NewUser(UserViewModel userVM)
{
User u = new User();
u.Name = null;


if (this.TryValidateObject(u))
{
TempData["NewUserCreated"] = "New user created sucessfully";
return RedirectToAction("Index");
}


return View();
}

我写了一个包装,使这个工作不那么笨重。

用法:

var response = SimpleValidator.Validate(model);


var isValid = response.IsValid;
var messages = response.Results;


或者,如果你只关心检查有效性,那就更严格了:

var isValid = SimpleValidator.IsModelValid(model);


完整资料来源:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;


namespace Ether.Validation
{
public static class SimpleValidator
{
/// <summary>
/// Validate the model and return a response, which includes any validation messages and an IsValid bit.
/// </summary>
public static ValidationResponse Validate(object model)
{
var results = new List<ValidationResult>();
var context = new ValidationContext(model);


var isValid = Validator.TryValidateObject(model, context, results, true);
         

return new ValidationResponse()
{
IsValid = isValid,
Results = results
};
}


/// <summary>
/// Validate the model and return a bit indicating whether the model is valid or not.
/// </summary>
public static bool IsModelValid(object model)
{
var response = Validate(model);


return response.IsValid;
}
}


public class ValidationResponse
{
public List<ValidationResult> Results { get; set; }
public bool IsValid { get; set; }


public ValidationResponse()
{
Results = new List<ValidationResult>();
IsValid = false;
}
}
}

或者这个要点: https://gist.github.com/kinetiq/faed1e3b2da4cca922896d1f7cdcc79b

还有另一种验证方法,它更容易重用—— 验证

这个库允许玩继承,不同的规则集为一个模型,并有许多其他很酷的功能。

通过这个库,验证规则的定义被从模型中分离出来,代码将看到下一个方向:

public class UserValidator:AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.Name).NotEmpty();
}
}

使用方法如下:

var validator = new UserValidator();
var validationResult = await validator.ValidateAsync(model);