Asp.net mvc 3 mvc 3.0中的验证规则

Asp.net mvc 3 mvc 3.0中的验证规则,asp.net-mvc-3,Asp.net Mvc 3,我有一个视图模型,这个模型中的3到4个视图都有这个模型,我还定义了验证规则。现在的问题是,在其中一个视图中,我想覆盖视图模型中两到三个字段的验证规则。那么我该怎么做呢?我不想为该视图创建新的视图模型。我的建议基本上是您不想要的:创建新的模型类,但使用继承来避免重复所需的属性。如果您坚决反对创建单独的模型,您可以考虑实现IValidatableObject,并让它在验证您希望更改的属性之前检查其他属性 编辑: 我不同意郁金香的答案,但充实我的建议,考虑一个场景,在其中你想保存用户的数据。从一个表单

我有一个视图模型,这个模型中的3到4个视图都有这个模型,我还定义了验证规则。现在的问题是,在其中一个视图中,我想覆盖视图模型中两到三个字段的验证规则。那么我该怎么做呢?我不想为该视图创建新的视图模型。

我的建议基本上是您不想要的:创建新的模型类,但使用继承来避免重复所需的属性。如果您坚决反对创建单独的模型,您可以考虑实现
IValidatableObject
,并让它在验证您希望更改的属性之前检查其他属性

编辑: 我不同意郁金香的答案,但充实我的建议,考虑一个场景,在其中你想保存用户的数据。从一个表单中,您正在创建一个用户;从另一个角度来看,您只是在更新(这有点牵强,但出于说明的目的)。“创建”表单可能需要引用用户的人的姓名,而“更新”表单可能不需要

使用继承,您可以执行以下操作:

public class SaveUserModel
{
    public int? UserId { get; set; }

    ...
}

public class CreateUserModel : SaveUserModel
{
    [Required]
    public string ReferredByName { get; set; }
}
使用
IValidatableObject
,您可以这样做:

public class SaveUserModel : IValidatableObject
{
    public int? UserId { get; set; }

    public string ReferredByName { get; set; }

    ...

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // if UserId is null, we are creating a user vs. updating
        if (UserId != null && string.IsNullOrWhiteSpace(ReferredBySiteUrl))
            yield return new ValidationResult("Please specify the name of the person who referred you.", new[] { "ReferredByName" });
    }
}
公共类SaveUserModel:IValidatableObject
{
public int?UserId{get;set;}
公共字符串referedbyname{get;set;}
...
公共IEnumerable验证(ValidationContext ValidationContext)
{
//如果UserId为null,我们将创建一个用户,而不是更新
if(UserId!=null&&string.IsNullOrWhiteSpace(referedbysiteurl))
返回新的ValidationResult(“请指定推荐您的人的姓名。”,new[]{“ReferredByName”});
}
}

重申一下,我并不是在试图给出我的答案。如果模型在不同的视图中完全相同,我倾向于重用它们,但通常有足够的差异来保证只需创建单独的模型。最后,在这种情况下,任何通过坚持干法而减轻的技术债务都会有一点清洗作用;模型易于维护。

我可以想到三个选项:

  • 使用AutoMapper制作一个单独的ViewModel来处理一些繁重的工作
  • 创建具有不同验证规则的子类
  • 创建上下文敏感的自定义
    ValidationAttribute
    (通过重写
    IsValid(Object,ValidationContext)
    方法,或依赖静态方法/属性中的其他上下文信息)
  • 例如,如果请求来自某个URL,则将忽略此必需的验证属性:

    public class CustomRequiredAttribute : RequiredAttribute
    {
        public override bool IsValid(object value)
        {
            if (HttpContext.Current.Request.Url != "urlwhennotrequired")
                return base.IsValid(value);
            return true;
        }
    }
    

    从MVC架构的角度来看,这正是使用视图模型的原因。 您应该为每种情况创建单独的视图模型。使用automapper(在codeplex上免费提供)在视图模型和实体之间复制值


    不要考虑不同的方式、继承等——这就是ViewModels的意思。

    如果你确实继承并使用继承,那么确保你从抽象类继承。我认为随着系统的增长,你可能会遇到一个场景,你的抽象类必须被严重修改,所以如果我是你,我会创建更多的视图模型,即使代码看起来是重复的。从长远来看,你会受益,因为你可以在尽可能少的副作用下修改部分应用程序。

    为了我自己的利益,你为什么不鼓励继承?+1因为没有推荐你自己不会做的事情。就像我做的那样。lol+1对于<代码>不要考虑不同的方式< /代码>:-我喜欢这个结论。同意这90%个。我认为没有必要有两个目的非常相似的不同视图模型。您可以创建CreateItemViewModel和UpdateItemViewModel,或者将这两个组合成SaveItemViewModel。。。大部分时间都在为我工作。@DarinDimitrov nice:)在我早期的mvc学习中,你的帖子实际上帮助我理解了这一点。我不明白,你能解释我吗,或者给我举个例子吗?为了对话/教育的目的添加了一些例子。对,你可以使用
    [CustomRequired]
    而不是
    [Required]
    例如,在少数几个您希望以不同方式处理的字段上,不要处理其他字段。