我似乎无法弄清楚如何验证具有部分ViewModel作为子对象的ViewModel的部分视图片段。这是我的最低级别的部分,它总是被用作其他表单标记内的部分视图:
namespace MVC3App.ViewModels
{
public class Payment : IValidatableObject
{
public decimal Amount { get; set; }
public int CreditCardNumber { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Amount < 20)
yield return new ValidationResult("Please pay more than $20", new string[] { "Amount" });
}
}
}
这是包含它的'main'ViewModel:
namespace MVC3App.ViewModels
{
public class NewCustomerWithPayment :IValidatableObject
{
public string Name { get; set; }
public int Age { get; set; }
public ViewModels.Payment PaymentInfo { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Age < 18)
yield return new ValidationResult("Too young.", new string[] { "Age" });
}
}
}
对于NewCustomerWithPayment的视图,我有这个:
@model MVC3App.ViewModels.NewCustomerWithPayment
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>NewCustomerWithPayment</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Age)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Age)
@Html.ValidationMessageFor(model => model.Age)
</div>
</fieldset>
@Html.Partial("Payment")
<p><input type="submit" value="Create" /></p>
}
部分视图“付款”总是在另一个Html.Beginform标记内呈现,它只是这样:
@model MVC3App.ViewModels.Payment
<h2>Payment</h2>
<fieldset>
<legend>Payment</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Amount)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Amount)
@Html.ValidationMessageFor(model => model.Amount)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.CreditCardNumber)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CreditCardNumber)
@Html.ValidationMessageFor(model => model.CreditCardNumber)
</div>
</fieldset>
我的问题是我无法在“付款”视图模型上进行验证。任何有经验的人都可以在ViewModel上使用IValidatableObject作为部分视图进行渲染并给我一个有效的验证模式吗?如果必须,我可以在没有JavaScript验证的情况下生活。
答案 0 :(得分:1)
这些答案都有一些很好的信息,但我的直接问题通过使用这个来解决:
@Html.EditorFor(model => model.PaymentInfo)
而不是:
Html.Partial("Payment", Model.PaymentInfo)
我很惊讶这种方法有效,但确实如此。 EditorFor帮助器像Html.Partial一样呈现部分视图,并自动连接验证。由于某种原因,它确实在子模型上调用了两次验证(在我的示例中为Payment),对于其他人来说似乎是一个报道的问题(http://mvcextensions.codeplex.com/workitem/10),所以我必须在每个模型上包含一个'HasBeenValidated'的布尔值,并在Validate的开头检查它调用
更新:您必须将视图移动到/ Views / Shared /下的EditorTemplates文件夹,以便EditorFor帮助程序使用该视图。否则,EditorFor将为您提供类型的默认编辑字段。
答案 1 :(得分:0)
这是一个复选框的自定义验证器的蹩脚示例:)我会写一个自定义验证器或使用正则表达式。这可能会让您走上正确的道路并且更容易。
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class CheckBoxMustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
#region IClientValidatable Members
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,
ControllerContext context)
{
yield return new ModelClientValidationRule
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "requiredcheckbox"
};
}
#endregion
public override bool IsValid(object value)
{
if (value is bool)
{
return (bool) value;
}
return true;
}
}