在ASP.NET MVC 5控制器中将验证逻辑与业务逻辑分开

在ASP.NET MVC 5控制器中将验证逻辑与业务逻辑分开

问题描述:

我有一个asp.net MVC 5网站.

I have an asp.net MVC 5 website.

我正在使用模型上的数据注释进行验证-例如

I am using data annotations on the model for validation - eg

[Required]
public string FirstName { get; set; }

但是,如果我想做一些更复杂的验证,请说要求日期在将来-我看到的所有示例都只是在控制器中执行验证-例如:

However, if I want to do something a bit more complicated with validation, say require a date to be in the future - all examples I have seen just perform validation in the controller - eg:

[HttpPost]
public ActionResult Edit(MyViewModel vm)
{
    // check date is in future
    if (vm.mydate < DateTime.Now())
        ModelState.IsValid = false;

    if (ModelState.IsValid)
    {
        //Business Logic
    }

甚至Web表单也使您可以将验证逻辑分离到CustomValidator中.将验证逻辑直接放入控制器并将其与业务逻辑混合在一起感觉很不对.

Even Web Forms let you separate validation logic out into a CustomValidator. It feels wrong putting validation logic into a controller directly and mixing it with business logic.

(注意-虽然我想回答如何使用数据注释解决这些特定问题,但我也想回答关于分离验证逻辑的更大问题).

(note - while I would like an answer to how to do this specific problems with Data Annotations - I would also like an answer to the bigger question about separating validation logic out).

是否有最佳实践或强制实施的框架来将其分开?在网上找到的任何示例网站中都没有看到它.

Is there a best practice, or a Framework mandated, way to separate this out? I haven't seen it in any example sites found online.

我是否为此过度担心-这是控制器执行验证的目的的一部分吗?我的业务逻辑应该在模型中吗? (BL实际上基本上只是在写数据库,所以也许甚至不算作BL?).

Am I unduly worrying about this - is this part of the purpose of a controller to perform validation? Should my business logic instead be in the Model? (the BL is largely really just writing to a database so maybe that doesn't even count as BL?).

thx.

您需要实现自定义验证属性.

You need to implement your custom Validation Attribute.

创建一个新类并添加:

public sealed class ValidFutureDate : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (value != null)
        {
            DateTime InputDate = Convert.ToDateTime(value);

            if (InputDate <= DateTime.Now)
            {
                return new ValidationResult("Inputed date must be in the future.");
            }
        }
        return ValidationResult.Success;
    }
}

您需要添加对System.ComponentModel.DataAnnotations

在ViewModel中,您可以像其余所有属性一样使用该属性:

And in your ViewModel, you can use the attribute like all the rest:

[Required]
[ValidFutureDate]
public DateTime Date { get; set; }