恕我直言,我喜欢下面的方法,并且已经广泛使用它,没有任何问题。这种方法的好处是它可以让你的模型保持干净并且可以分离关注点。 Model 的验证逻辑是完全独立的。
尝试使用FluentValidation。您可以详细阅读here。这是一个 NuGet 包,您可以通过 NuGet.org download。安装后,您可以在ConfigureServices 注册它,如下所示:
1 public void ConfigureServices(IServiceCollection services)
2 {
3 services.AddMvc(setup => {
4 //...mvc setup...
5 }).AddFluentValidation(configuration => configuration
6 .RegisterValidatorsFromAssemblyContaining<Startup>());
7 }
第 5 行和第 6 行将自动查找从 AbstractValidator 继承的任何公共、非抽象类型,并将它们注册到容器中。然后,您为Model 定义您的AbstractValidator,如下所示
在创建 AbstractValidator 之前
我知道您提到您希望避免将 PublishedAt 类型更改为字符串。不过,我建议你考虑一下。这将使参数的验证变得容易,否则,自动模型绑定可能会以不同的格式绑定它,并且自定义模型绑定比以下更棘手。
如果你真的想避免将PublishedAt 更改为string,
您可以通过稍微更改规则来尝试相同的方法并查看
如果这对你有用
public class ModelValidator : AbstractValidator<Model>
{
public ModelValidator()
{
// add a rule that Date must be in the past, shouldn't be empty
// and in the correct format
RuleFor(model => model.PublishedAt)
.Cascade(CascadeMode.StopOnFirstFailure)
.Must(date => !string.IsNullOrWhiteSpace(date))
.WithMessage("PublishAt is a required parameter")
.Must(arg =>
{
if (DateTime.TryParseExact(arg.ToString(), new[] { "dd-MMM-yyyy" }, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
{
return date < DateTime.Now;
}
return false;
})
.When(model => !string.IsNullOrWhiteSpace(model.PublishedAt))
.WithMessage("Argument PublishAt is invalid. Please specify the date in dd-MMM-yyy and should be in the past");
}
}
上述验证器将在模型绑定过程之后执行,如果验证失败,WithMessage 语句会将错误添加到 ModelState。因为你有 [ApiController] 属性。您的模型将被验证并返回您在 WithMessage 语句中指定的消息。
或者您可以手动检查操作方法中是否有ModelState.IsValid,并返回带有ModelState 的ObjectResult。