c# - ViewModel 中对象的验证不添加 CSS 验证类

标签 c# .net asp.net-mvc-3 validation

我有以下 View 模型:

public class Search {
    public int Id { get; set; }

    [Required(ErrorMessage = "Please choose a name.")]
    public string Name { get; set; }

    [ValidGroup(ErrorMessage = "Please create a new group or choose an existing one.")]
    public Group Group { get; set; }
}

public class Group {
    public int Id { get; set; }
    public string Name { get; set; }
}

我定义了一个自定义验证属性,如下所示:

public class ValidGroupAttribute : ValidationAttribute {
    public override bool IsValid(object value) {
        if (value == null)
            return false;

        Group group = (Group)value;

        return !(string.IsNullOrEmpty(group.Name) && group.Id == 0);
    }
}

我有以下看法(为简洁省略了一些):

    @Html.ValidationSummary()

    <p>
        <!-- These are custom HTML helper extensions. -->
        @Html.RadioButtonForBool(m => m.NewGroup, true, "New", new { @class = "formRadioSearch", id = "NewGroup" })
        @Html.RadioButtonForBool(m => m.NewGroup, false, "Existing", new { @class = "formRadioSearch", id = "ExistingGroup" })
    </p>
    <p>
        <label>Group</label>
        @if (Model.Group != null && Model.Group.Id == 0) {
            @Html.TextBoxFor(m => m.Group.Name)
        }
        else {
            @Html.DropDownListFor(m => m.Group.Id, Model.Groups)
        }
    </p>

我遇到的问题是验证类 input-validation-error 未应用于组输入。我认为这是因为框架试图找到一个带有 id="Group" 的字段,并且正在生成的标记有 id="Group_Id"id=群组名称。有什么方法可以申请类(class)吗?

http://f.cl.ly/items/0Y3R0W3Z193s3d1h3518/Capture.PNG

更新

我已经尝试在组 View 模型上实现 IValidatableObject 而不是使用验证属性,但我仍然无法应用 CSS 类:

public class Group : IValidatableObject
{
    public int Id { get; set; }
    public string Name { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
        if (string.IsNullOrEmpty(Name) && Id == 0) {
            yield return new ValidationResult("Please create a new group or select an existing one.", new[] { "Group.Name" });
        }
    }
}

更新2

self 验证不起作用。我认为这是因为 MVC 框架中未使用 ValidationResult 构造函数中的第二个参数。

发件人:http://www.devtrends.co.uk/blog/the-complete-guide-to-validation-in-asp.net-mvc-3-part-2

In some situations, you might be tempted to use the second constructor overload of ValidationResult that takes in an IEnumerable of member names. For example, you may decide that you want to display the error message on both fields being compared, so you change the code to this:

return new ValidationResult( FormatErrorMessage(validationContext.DisplayName), new[] { validationContext.MemberName, OtherProperty });

If you run your code, you will find absolutely no difference. This is because although this overload is present and presumably used elsewhere in the .NET framework, the MVC framework completely ignores ValidationResult.MemberNames.

最佳答案

我想出了一个可行的解决方案,但显然是一种变通方法。

我删除了验证属性并创建了一个自定义模型绑定(bind)器,它手动将错误添加到 Group.Name 属性的 ModelState 字典中。

public class SearchBinder : DefaultModelBinder {
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext,
       PropertyDescriptor propertyDescriptor) {
        if (propertyDescriptor.Name == "Group" &&
            bindingContext.ValueProvider.GetValue("Group.Name") != null &&
            bindingContext.ValueProvider.GetValue("Group.Name").AttemptedValue == "") {
            ModelState modelState = new ModelState { Value = bindingContext.ValueProvider.GetValue("Group.Name") };
            modelState.Errors.Add("Please create a new group or choose an existing one.");
            bindingContext.ModelState.Add("Group.Name", modelState);
        }
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }
}

// Register custom model binders in Application_Start()
ModelBinders.Binders.Add(typeof(SearchViewModel), new SearchBinder());

ModelState["Group.Name"] 现在有一个错误条目,CSS 类正在标记中呈现。

不过,如果有一种方法可以在 MVC 中使用惯用验证来做到这一点,我会更愿意。

已解决!

找到了一个合适的方法来做到这一点。我在自验证类中指定了错误的属性名称,因此添加到 ModelState 字典的键是 Group.Group.Name。我所要做的就是更改返回的 ValidationResult

yield return new ValidationResult("Please create a new group or select an existing one.", new[] { "Name" });

关于c# - ViewModel 中对象的验证不添加 CSS 验证类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8844222/

相关文章:

c# - 如何获取嵌套属性

c# - 如何将参数名称传递给方面方法

c# - StackExchange.Redis SetAdd(key, val) 因 key = GUID 而崩溃

asp.net-mvc-3 - 抛弃 ActiveRecord 和 NHibernate——如何重新架构?

c# - IValidatableObject 和依赖注入(inject)支持

c# - 无法加载文件或程序集 'System.Net.Http' 或其依赖项之一

.net - T4 模板问题

c# - 将 HttpPostedFileBase - pdf 类型转换为 png/jpg 类型

c# - 没有断点时调试器停止 VS2010

c# - ASP.NET-MVC3 中 "Self Validate Model"中的客户端验证