cw_*_*dev 5 validation asp.net-mvc-validation unobtrusive-validation asp.net-mvc-3
题
我已经创建了服务器端属性级别验证属性.但是,我没有将它应用于单个字段,而是将其应用于List.这允许我作为一个整体验证模型.
我现在需要知道如何使用MVC 3中内置的不显眼的客户端验证将其转换为工作.
我目前的代码如下,以说明我的问题......
脚本
基本方案是按GroupNo字段分组的List中每行的所有Quantity值的总计.如果任何组的总和超过10,则应显示错误.
我在前一篇文章中得到了一个答案,使得这个工作服务器端使用针对List的验证属性...
该模型:
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; }
}
Run Code Online (Sandbox Code Playgroud)
和验证属性本身:
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
最后你的控制器动作将与视图模型一起使用:
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);
}
...
}
Run Code Online (Sandbox Code Playgroud)
接下来是相应的强类型视图:
@model MyViewModel
@Html.ValidationSummary()
@using (Html.BeginForm())
{
@Html.EditorFor(x => x.Items)
<button type="submit">Go go go</button>
}
Run Code Online (Sandbox Code Playgroud)
最后一位是相应的编辑器模板,它将自动为Items集合的每个元素呈现,这样你甚至不需要为循环(~/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)
Run Code Online (Sandbox Code Playgroud)
客户端不显眼的验证可能吗?
我希望使用不引人注目的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
Run Code Online (Sandbox Code Playgroud)
注意:VB和C#的混合只是因为我在C#中回答了上一个问题.该项目是在VB中,但我不介意在C#中的答案.
我在JS文件中创建了适配器:
jQuery.validator.unobtrusive.adapters.addBool("itemscheck");
Run Code Online (Sandbox Code Playgroud)
......而且......
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;
});
Run Code Online (Sandbox Code Playgroud)
有没有办法把这个挂起来工作不引人注目?
这是不可能的,因为您的自定义属性放置在集合属性中,并且data-*根本没有发出任何 HTML5 属性。不显眼的客户端验证框架不支持这种情况。如果您需要客户端验证,您可以直接编写自定义 jquery 验证规则来处理这种情况。