不引人注目的验证在MVC4中保持突破

时间:2012-10-07 15:50:59

标签: jquery asp.net-mvc asp.net-mvc-4 unobtrusive-validation

我一直有一个让我绝对疯狂的奇怪问题。

在它运作良好之后,它开始出现以下错误:

Validation type names in unobtrusive client validation rules must be unique. The following     
validation type was seen more than once: required

此错误首先在Area / Admin / WebSites中的某个控制器上启动。但是,一旦我的身份验证cookie过期,我就会在我的登录页面上以及EditFor(m => m.UserName)行中获得它。我梳理了我的代码,在任何可能远程命名相同的模型上的任何地方寻找重复的必需属性,但无济于事。

我甚至进入了我的LoginViewModel,删除了[Required] From UserName。错误移至EditFor(m => m.Password)。我也从密码中删除了必需,并且错误移动了RememberMe行,但该成员上根本没有必需属性。事实上,我在任何其他任何地方都没有其他名称甚至远程命名为RememberMe。

好吧,我放弃并开始从头开始重建webSite项目(不是解决方案的其余部分),但最终仍然有同样的事情。

出于绝望,我从头开始重建整个解决方案,只复制* .cs文件并手动重新加载所有引用,认为某处有重复的引用。

一旦我再次构建MVC4项目,我就分阶段进行,看看能否知道发生了什么。它做得很好,加载,我可以登录等,直到我开始添加区域。起初我只是将Areas文件夹直接复制到项目中(所有命名空间名称都相同,所以这应该没问题)。但果然我开始正确地得到这个错误。

好的,所以我开始按照我最初创建它们的相反顺序删除控制器。在我完全删除了Areas文件夹之前,该网站从未恢复正常。

测试一下,一旦我在项目中创建了一个Areas文件夹,它就会中断。如果我使用GUI创建新区域也是如此。

好的,回到绘图板。从头开始重新创建MVC4项目,这次是在解决方案之外,并且只引入了对我的解决方案至关重要的两个关键NuGet包:Ninject.MVC3和Mvc3ControlsKit(来自nuget的一个用于3和4)。好的,一切都终于开始了。此时,我的Jquery是版本1.7.2,带有MVC4附带的默认Jquery UI。

在某些时候,我遇到了jquery对话框没有关闭的问题所以我从NuGet安装了JQuery 1.8.2和最新的JQuery UI。一切正常,直到我在管理区域添加一个完全空白的控制器,然后再次出现此错误。

好的,再次回到绘图板......我分阶段重建它,在每个点进行测试。这次没有安装最新的JQuery好东西。一切都恢复正常。添加了一个新控制器,然后是两个。好的,制作了这个版本的有效副本并将其放在一边。将Jquery和Jquery UI更新到最新版本。在该区域添加一个新的控制器,它仍然继续让我完全失望。

我的实体都使用Fluent API配置我的实体,根本没有DataAnnotatian属性。有任何想法吗?我一直在等待它再次破裂。

修改

以下是我刚才想到的更多信息。我的LogIn Partial View中的这行代码出现错误。我的模特是

public class LoginViewModel 
{
    [Required]
    [Display(Name = "User Name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }

    /// <summary>
    /// Role
    /// </summary>
    public string Role { get; set; }

}

在视图中调用此行时发生错误:

@Html.TextBoxFor(m => m.UserName)

此时,Ninject接管并在Ninject.Web.Mvc.Validation.NinjectDataAnnotationsModelValidatorProvider类中的以下方法返回后立即进行上述不显眼的验证错误。此外,我已确认此方法已正确识别所需的验证并注入它们。此方法中没有发生例外,但事后却没有。

protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        var validators = base.GetValidators(metadata, context, attributes);
        foreach (var modelValidator in validators.OfType<DataAnnotationsModelValidator>())
        {
            var attribute = this.getAttributeMethodInfo.Invoke(modelValidator, new object[0]);
            this.kernel.Inject(attribute);
        }

        return validators;
    }

4 个答案:

答案 0 :(得分:11)

解决方案(如果正在使用Ninject)是取消绑定绑定。

kernel.Unbind&LT; ModelValidatorProvider&GT;();

答案 1 :(得分:5)

发生错误是因为您尝试在项目中使用混合验证解决方案,并且两个提供程序正在尝试为字段添加不显眼的必需验证,因此会出现重复问题。

确保您没有同时使用dataannotation和Fluent验证来对同一属性执行相同的验证(如您的情况所需)。

答案 2 :(得分:2)

对于这个问题的每个人来说,这不一定是一个令人满意的答案,但我通过切换到Unity来解决我的问题。我已经确定,是的,这是因为,正如马克所说,这可能是由于混合验证。我在我的代码中使用DataAnnotation;可能是Ninject在内部使用流利验证,但我不知道该如何肯定,并且没有精力继续这一追求,因为我找到了一个令我满意的答案。

我喜欢Ninject,但在我的情况下,最新版本Unity实际上同样易于使用,因为我所要做的就是添加一个文件(bootstrapper.cs)并从启动事件中调用BootStrapper.BuildUnityContainer()。所以,我现在会坚持使用这个解决方案。

答案 3 :(得分:1)

我在使用流畅验证的MVC4项目中遇到了同样的错误。我的错误是我使用了.NotNull()和.NotEmpty(对于同一个字段):

RuleFor(i => i.SomeValue).NotNull().NotEmpty();

删除最后一个.NotEmpty()解决了这个问题。