假设我有一个
Person
课程,其中有 FirstName
和 LastName
。我希望用户必须在 UI 中至少输入两个值之一,但他可能不必输入每个值。
如果我将
Required
属性/数据注释放在每个属性/数据注释上,那么这两个属性/数据注释都是必需的。
如何为此规则进行服务器端验证(也包括客户端验证)?
您可以为此使用自定义属性。简而言之,自定义属性将检索这两个值,然后确保至少有一个值具有值。请参阅此页了解更多信息。这是一个示例(未经测试的代码):
[AttributeUsage(AttributeTargets.Property, AllowMultiple =false, Inherited = false)]
public class ValidatePersonName: ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
string FirstName = (string)validationContext.ObjectType.GetProperty("FirstName").GetValue(validationContext.ObjectInstance, null);
string LastName = (string)validationContext.ObjectType.GetProperty("LastName").GetValue(validationContext.ObjectInstance, null);
//check at least one has a value
if (string.IsNullOrEmpty(FirstName) && string.IsNullOrEmpty(LastName))
return new ValidationResult("At least one is required!!");
return ValidationResult.Success;
}
}
用途:
class Person{
[ValidatePersonName]
FirstName{get;set;}
LastName{get;set;}
}
您需要在前端和后端进行验证。
前端验证应确保输入正确,以便在与服务器进行另一次往返之前向用户提供直接反馈。在这里,您需要防止合法但错误的字符串:
另一方面,“Asdf”也不是一个名字,而“X Æ A-Xii”是一个合法的名字(问问埃隆·马斯克)。
后端验证应该处理安全问题。
如果您只想允许实例化依赖属性,则需要实现相应的构造函数。如果您以相同的参数类型结束(这里,FirstName 和 LastName 都是字符串类型,因此不可能有不同的构造函数),您可以为构造函数提供一个附加参数,该参数决定输入参数应分配到的位置。此外,您只允许私有集合访问器,并在必要时提供额外的设置方法:
public class Person {
public string FirstName { get; private set; } = string.Empty;
public string LastName { get; private set; } = string.Empty;
public Person(string firstName, string lastName) {
FirstName = firstName;
LastName = lastName;
}
public Person(string name, bool nameIsFirstName = false) {
if (nameIsFirstName) {
FirstName = name;
} else {
LastName = name;
}
}
public void UpdateNames(string firstName, string lastName) {
FirstName = firstName;
LastName = lastName;
}
public void UpdateName(string name, bool nameIsFirstName = false) {
if (nameIsFirstName) {
FirstName = name;
} else {
LastName = name;
}
}
}
此外,您还应该防止重复: