我已经在多个地方搜索了这个问题,但无法准确找到我想要的东西。假设我有这个MVC模型结构:
public class Person {
[Required]
public string Name { get; set; }
public int Age { get; set; }
}
public class Workers {
[AgeRequired]
public Person Pilots { get; set; }
public Person Chefs { get; set; }
}
这是我的cshtml代码:
@Model Workers
<div>
<label asp-for="Pilots.Name"></label>
<input asp-for="Pilots.Name"></input>
<span asp-validation-for="Pilots.Name"></span>
</div>
<div>
<label asp-for="Pilots.Age"></label>
<input asp-for="Pilots.Age"></input>
<span asp-validation-for="Pilots.Age"></span>
</div>
<div>
<label asp-for="Chefs.Name"></label>
<input asp-for="Chefs.Name"></input>
<span asp-validation-for="Chefs.Name"></span>
</div>
<div>
<label asp-for="Chefs.Age"></label>
<input asp-for="Chefs.Age"></input>
<span asp-validation-for="Chefs.Age"></span>
</div>
人员是一个通用模型类,其中包含有关飞行员或厨师的信息。我想要的是我的AgeRequired自定义验证属性,以使仅当提及飞行员而不是厨师时才需要Age。可以吗?
提交表格后,我可以在后端工作,但是我也希望它也可以在前端工作。这是我的属性代码:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class AgeRequiredAttribute: ValidationAttribute, IClientModelValidator
{
public override bool IsValid(object value)
{
Workers workers = value as Workers;
return workers.Age > 0;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ClientModelValidationContext context)
{
yield return new ModelClientValidationRule("agerequired", "{0} is a required field.");
}
}
}
这是我用于前端验证的javascript代码:
/// <reference path="jquery.validate.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
$.validator.addMethod("agerequired",
function (value, element, parameters) {
return value > 0;
});
$.validator.unobtrusive.adapters.add("agerequired", [], function (options) {
options.rules.agerequired= {};
options.messages["agerequired"] = options.message;
});
ClientValidationEnabled和UnobstrusiveJavaScriptEnabled都设置为true。
当我在“年龄”字段本身上具有此自定义属性时,它将起作用,但是这对于飞行员和厨师都是必需的。我只希望飞行员需要它。
提前感谢您的帮助!
答案 0 :(得分:0)
实际上,我能够为感兴趣的人创建作品。
如果将由MVC生成的data-val- [attribute]直接放入输入标签或选择标签中,然后输入要抛出的错误消息,它将进行前端验证,并且仍然进行后端验证,因为MVC会注意到复杂对象中包含信息。这不是理想的,但可能是我将要做的。
例如:
@Model Workers
<div>
<label asp-for="Pilots.Name"></label>
<input asp-for="Pilots.Name"></input>
<span asp-validation-for="Pilots.Name"></span>
</div>
<div>
<label asp-for="Pilots.Age"></label>
<input asp-for="Pilots.Age" data-val-agerequired="Age is Required for Pilots."></input>
<span asp-validation-for="Pilots.Age"></span>
</div>
<div>
<label asp-for="Chefs.Name"></label>
<input asp-for="Chefs.Name"></input>
<span asp-validation-for="Chefs.Name"></span>
</div>
<div>
<label asp-for="Chefs.Age"></label>
<input asp-for="Chefs.Age"></input>
<span asp-validation-for="Chefs.Age"></span>
</div>
会工作。这不是理想的方法,但是它使我们可以将MVC后端验证保留在同一位置。
答案 1 :(得分:0)
另一种选择是在基类中将人的年龄作为可选。
public int? Age { get; set; }
从Person继承厨师和飞行员。在试用版中,将年龄值设为非可选-您可能还希望使用数据注释来确保年龄最小化
public new int Age { get; set; }
该模型现在是“人员”列表。客户端应该能够确定哪个是可选的,哪个不是