针对正在验证的实体采取的行动的模型验证

时间:2014-09-18 10:46:36

标签: c# asp.net-mvc validation asp.net-web-api data-annotations

我们如何根据对特定实体采取的行动来验证数据?还有哪些其他更先进的替代方案可用于数据注释模型验证?可能可插入Asp.net MVC和WebAPI,因此验证仍在自动完成。

实施例

假设用户加入了Web应用程序的表单。

public class User
{
    // required when providing user as input
    // not provided when creating new instance
    public int Id { get; set; }

    // required when user joins and of specific format AND IS UNIQUE based on data store users
    // optional when providing user as input
    public string Email { get; set; }

    ...
}

也许对象继承可能会有所帮助,但就像我想的那样,继承只会像黑客一样。基类几乎没有任何属性,我们可能最终得到几个非常相似(属性)的类,但使用不同的注释只是为了使用数据注释。这并不好。

期望的实施

我正在考虑基于对特定实体采取的行动进行验证。所以我们可以定义类似的东西:

public class User
{
    [Required(Action = ValidationAction.Provide)] // or whatever action we'd define
    public int Id { get; set; }

    [Required(Action = ValidationAction.Create)]
    [IsUnique(Action = ValidationAction.Create)] // custom DataAnnotations validator
    [EmailAddress]
    public string Email { get; set; }

    ...
}

Asp.net MVC和WebAPI控制器操作需要某种属性来提供有关特定实体的参数的信息

[HttpPost]
[ValidateForAction("user", ValidationAction.Create)]
[ValidateForAction("user.InvitedBy", ValidationAction.Provide)]
public ActionResult Join(User user)
{
    ...
}

或为所有参数(及其子树中的对象实体)统一设置

[HttpPost]
[ValidateForAction(ValidationAction.Create)]
public ActionResult Join(User user)
{
    ...
}

当控制器上没有ValidateForActionAttribute时,操作验证应该只检查与验证操作无关的注释(例如我的实体示例上面设置的EmailAddressAttribute)。

类似的示例可能是添加答案的Stackoverflow场景,其中发布的答案详细信息将通过创建操作进行验证,并且相应的问题实体(答案中的属性)将根据提供操作进行验证,因为我们主要只需要Id

有没有这样的验证库?有人做过类似的事吗?

您将如何进行此类验证?

1 个答案:

答案 0 :(得分:0)

这听起来类似于requireif验证器,其中验证依赖于另一个属性。但是,模型验证在这里不起作用,因为模型“应该”独立于视图或控制器。

假设您有一个与控制器上的各个操作相关联的视图模型,那么视图模型可以使用与视图要求一致的数据注释。有关MVVM模式的更多详细信息,请参阅ASP.Net MVC and MVVM

关于Id的最后一条评论。不确定Required属性是否有效,因为int的默认值是有效值。也许正则表达式? ([1-9] | [0-9] {2,10})

public class RegistrationController

    [HttpPost]
    public ActionResult Provide(UserProvideViewModel user)
    {
         ...
    }

    [HttpPost]
    public ActionResult Join(UserJoinViewModel user)
    {
         ...
    }
}

[MetadataType(typeof(UserProvideViewModel_Validation))]
public partial class UserProvideViewModel : User
{
    // properties unique to the view model
}

public class UserProvideViewModel_Validation
{
    [RegularExpression(@"^([1-9]|\d{2,10})$")]
     public Id { get; set; }
}

[MetadataType(typeof(UserJoinViewModel_Validation))]
public partial class UserJoinViewModel : User
{
    // properties unique to the view model
}

public class UserJoinViewModel_Validation
{
     [Required]
     [EmailAddress]
     public Email { get; set; }
}