【问题标题】:MVC 3 Unobtrusive validation of a listMVC 3 不显眼的列表验证
【发布时间】:2012-07-13 13:51:36
【问题描述】:

问题

我创建了一个服务器端属性级别验证属性。但我没有将其应用于单个字段,而是将其应用于列表。这使我可以将模型作为一个整体进行验证。

我现在需要知道如何使用 MVC 3 中内置的不显眼的客户端验证将其转换为工作。

下面是我当前的代码来说明我的问题...

场景

基本方案是对由 GroupNo 字段分组的 List 中每一行的所有 Quantity 值求和。如果任何组的总和超过 10,则应显示错误。

我在上一篇文章中得到了一个答案,以便使用针对列表的验证属性使这项工作在服务器端工作......

型号:

public class ItemDetails
{
    public int SerialNo { get; set; }
    public string Description { get; set; }
    public int GroupNo { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
}

public class MyViewModel
{
    [EnsureMaxGroupItems(10, ErrorMessage = "You cannot have more than 10 items in each group")]
    public IList<ItemDetails> Items { get; set; }
}

以及验证属性本身:

[AttributeUsage(AttributeTargets.Property)]
public class EnsureMaxGroupItemsAttribute : ValidationAttribute
{
    public int MaxItems { get; private set; }

    public EnsureMaxGroupItemsAttribute(int maxItems)
    {
        MaxItems = maxItems;
    }

    public override bool IsValid(object value)
    {
        var items = value as IEnumerable<ItemDetails>;
        if (items == null)
        {
            return true;
        }

        return items
            .GroupBy(x => x.GroupNo)
            .Select(g => g.Sum(x => x.Quantity))
            .All(quantity => quantity <= MaxItems);
    }
}

最后,您的控制器操作将与视图模型一起使用:

public ActionResult ListItems()
{
    var model = new MyViewModel
    {
        Items = ItemsRepository.GetItems()
    };
    return View(model);
}

[HttpPost]
public ActionResult ListItems(MyViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    ...
}

接下来是对应的强类型视图:

@model MyViewModel
@Html.ValidationSummary()
@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.Items)
    <button type="submit">Go go go</button>
}

最后一位是对应的编辑器模板,它将为 Items 集合的每个元素自动呈现,这样你甚至不需要编写 for 循环 (~/Views/Shared/EditorTemplates/ItemDetails.cshtml):

@model ItemDetails
@Html.HiddenFor(x => x.SerialNo)
@Html.LabelFor(x => x.Description)
@Html.HiddenFor(x => x.GroupNo)
@Html.LabelFor(x => x.Price)
@Html.TextBoxFor(x => x.Quantity)

可以进行客户端非侵入式验证吗?

我希望使用不显眼的 MVC 验证来验证所有内容。但我无法弄清楚如何针对整个列表不显眼地验证 EnsureMaxGroupItemsAttribute 属性。

我已经以这种方式实现了 IClientValidatable:

    Public Function GetClientValidationRules(metadata As System.Web.Mvc.ModelMetadata, context As System.Web.Mvc.ControllerContext) As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.ModelClientValidationRule) Implements System.Web.Mvc.IClientValidatable.GetClientValidationRules

        Dim result = New List(Of ModelClientValidationRule)

        Dim rule = New ModelClientValidationRule() With { _
            .ErrorMessage = "You cannot have more than 10 items in each group", _
            .ValidationType = "itemscheck"}

        result.Add(rule)

        Return result

    End Function

注意:VB 和 C# 的混合只是因为我之前提出的问题是用 C# 回答的。该项目在 VB 中,但我不介意 C# 中的答案。

我已经在我的 JS 文件中创建了适配器:

jQuery.validator.unobtrusive.adapters.addBool("itemscheck"); 

...和...

jQuery.validator.addMethod("itemscheck", function (value, element, params) {
    // The check has been omitted for the sake of saving space.  
    // However this method never gets called
    return false;
});

有没有办法让它不引人注目地工作?

【问题讨论】:

  • 阅读stackoverflow.com/questions/4748703/…后我认为这是不可能的。虽然这谈论的是 IValidatableObject 而不是 ValidationAttribute 我只能想,因为我将它分配给一个 List 效果是一样的。我认为我唯一的解决方案是完全删除不显眼的验证,只使用 jQuery 进行验证。

标签: asp.net-mvc-3 validation unobtrusive-validation asp.net-mvc-validation


【解决方案1】:

这是不可能的,因为您的自定义属性放置在集合属性中,并且根本没有发出 HTML5 data-* 属性。不显眼的客户端验证框架不支持这种情况。如果您需要客户端验证,您可以直接编写自定义 jquery 验证规则来处理这种情况。

【讨论】:

  • 谢谢,我认为这可能是不可能的。我之前没有真正尝试过在不使用不显眼的情况下进行任何验证。就目前而言,我在提交表单的 js 文件中有自己的函数(我没有标准的提交按钮)。是否只是将我的验证码放入此函数中,如果无效我不提交。这样做不会在页面上内置验证摘要,所以我正在考虑适当地显示/隐藏。或者您是否暗示有一种更自动的方法可以做到这一点,如果是这样,它可以与验证摘要一起使用吗?
  • 我会直接插入 jQuery 验证插件。
  • 谢谢,我想我正在慢慢弄清楚,将 jQuery.validate.addMethod 添加到我的 js 中。几个问题:- 1)我将如何连接表单级别的验证检查,就像我上面的原始问题一样?即使它适用于不同行上的多个控件,我是否必须将其连接到控件? 2)通过不显眼的验证,我习惯了验证摘要 - 对插件做同样的事情,我是否必须自定义 ShowErrors 并建立自己的等效项? 3)服务器端错误如何与此结合使用?我还会有一个 Html.ValidationSummary 来为他们服务吗?
  • 您可以连接每个数量字段的验证。这样,当它的值更改时,验证就会启动。就显示错误消息而言,您可以覆盖 jquery validate 插件的 showError 方法,该方法允许您在 ValidationSummary 帮助器生成的 span 占位符中显示错误消息。
猜你喜欢
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-17
  • 1970-01-01
  • 2011-12-22
相关资源
最近更新 更多