我在ASP.NET MVC项目中使用EF数据注释,对于必填字段,我定义了如下字段:
型号:
[Required(ErrorMessage = "Required!");
public string PhoneHome{ get; set; }
[Required(ErrorMessage = "Required!");
public string PhoneWork{ get; set; }
[Required(ErrorMessage = "Required!");
public string PhoneMobile { get; set; }
视图:
@Html.TextBoxFor(m => m.PhoneHome)
@Html.ValidationMessageFor(m => m.PhoneHome, null, new { @class = "field-validation-error" })
@Html.TextBoxFor(m => m.PhoneWork)
@Html.ValidationMessageFor(m => m.PhoneWork, null, new { @class = "field-validation-error" })
@Html.TextBoxFor(m => m.PhoneMobile )
@Html.ValidationMessageFor(m => m.PhoneMobile , null, new { @class = "field-validation-error" })
我只想强制这些字段之一(如果用户填写这些字段之一就可以,但是如果他不填写其中任何一个,我想显示错误消息并且不要让他提交表单),但不知道最合适,最聪明的方法来执行此操作吗?我应该在提交时使用JavaScript检查所有这些字段并显示必要的错误消息吗?还是应该仅使用数据注释来执行此操作?
答案 0 :(得分:1)
好的,所以我举了一个例子。我创建了一个自定义验证属性,该属性具有一些参数,例如所需的属性和多少(最小和最大)。命名不是最好的,但是可以完成工作(未经测试)。如果您不关心客户端上的验证,则可以删除ICientValidatable(使用jquery验证,不打扰...)。
属性是这样制作的:
public class OptionalRequired : ValidationAttribute, IClientValidatable
{
/// <summary>
/// The name of the client validation rule
/// </summary>
private readonly string type = "optionalrequired";
/// <summary>
/// The (minimum) ammount of properties that are required to be filled in. Use -1 when there is no minimum. Default 1.
/// </summary>
public int MinimumAmmount { get; set; } = 1;
/// <summary>
/// The maximum ammount of properties that need to be filled in. Use -1 when there is no maximum. Default -1.
/// </summary>
public int MaximumAmmount { get; set; } = -1;
/// <summary>
/// The collection of property names
/// </summary>
public string[] Properties { get; set; }
public OptionalRequired(string[] properties)
{
Properties = properties;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
int validPropertyValues = 0;
// Iterate the properties in the collection
foreach (var propertyName in Properties)
{
// Find the property
var property = validationContext.ObjectType.GetProperty(propertyName);
// When the property is not found throw an exception
if (property == null)
throw new ArgumentException($"Property {propertyName} not found.");
// Get the value of the property
var propertyValue = property.GetValue(validationContext.ObjectInstance);
// When the value is not null and not empty (very simple validation)
if (propertyValue != null && String.IsNullOrEmpty(propertyValue.ToString()))
validPropertyValues++;
}
// Check if the minimum allowed is exceeded
if (MinimumAmmount != -1 && validPropertyValues < MinimumAmmount)
return new ValidationResult($"You are required to fill in a minimum of {MinimumAmmount} fields.");
// Check if the maximum allowed is exceeded
else if (MaximumAmmount != -1 && validPropertyValues > MaximumAmmount)
return new ValidationResult($"You can only fill in {MaximumAmmount} of fields");
//
else
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
ModelClientValidationRule rule = new ModelClientValidationRule();
rule.ErrorMessage = "Enter your error message here or manipulate it on the client side";
rule.ValidationParameters.Add("minimum", MinimumAmmount);
rule.ValidationParameters.Add("maximum", MaximumAmmount);
rule.ValidationParameters.Add("properties", string.Join(",", Properties));
rule.ValidationType = type;
yield return rule;
}
}
然后在类/视图模型上使用它:
public class Person
{
[OptionalRequired(new string[] { nameof(MobileNumber), nameof(LandLineNumber), nameof(FaxNumber) }, MinimumAmmount = 2)]
public string MobileNumber { get; set; }
public string LandLineNumber { get; set; }
public string FaxNumber { get; set; }
}
使用此配置,您需要至少填写2个必填字段,否则将显示错误。 您可以将属性放在每个属性上,以便在所有属性上弹出错误消息。这就是你想要的
为了进行客户端验证,我在属性上添加了接口,并设置了不同的参数,但是我没有JavaScript本身。您需要查找它(例如here)
此代码未经测试,但我认为它可以使您很好地了解事情的完成方式。
答案 1 :(得分:0)
public class MyModel : IValidatableObject
{
[Required(ErrorMessage = "Required!");
public string PhoneHome{ get; set; }
[Required(ErrorMessage = "Required!");
public string PhoneWork{ get; set; }
[Required(ErrorMessage = "Required!");
public string PhoneMobile { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if ((PhoneHome+PhoneWork+PhoneMobile).Length < 1)
{
yield return new ValidationResult("You should set up any phone number!", new [] { "ConfirmForm" });
}
}
}