数据模型需要两个属性之一

问题描述 投票:0回答:2

假设我有一个

Person
课程,其中有
FirstName
LastName
。我希望用户必须在 UI 中至少输入两个值之一,但他可能不必输入每个值。

如果我将

Required
属性/数据注释放在每个属性/数据注释上,那么这两个属性/数据注释都是必需的。

如何为此规则进行服务器端验证(也包括客户端验证)?

asp.net-mvc asp.net-mvc-3 entity-framework entity-framework-4 asp.net-mvc-4
2个回答
18
投票

您可以为此使用自定义属性。简而言之,自定义属性将检索这两个值,然后确保至少有一个值具有值。请参阅此页了解更多信息。这是一个示例(未经测试的代码):

[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;}
}

0
投票

您需要在前端和后端进行验证。

前端验证应确保输入正确,以便在与服务器进行另一次往返之前向用户提供直接反馈。在这里,您需要防止合法但错误的字符串:

  • null(因为字符串是引用类型)
  • “”(空)
  • “”(空格)
  • “。” (不是名字)
  • “4”(不是名字)
  • “Hans”(是一个错误输入的名字,因为它有一个不必要的前导空格)
  • “hans”(是错误输入的名称,因为第一个字符应为大写)

另一方面,“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;
    }
  }
}

此外,您还应该防止重复

  • 前端:使用请求/有效负载缓冲区来防止对服务器的意外双重调用
  • 后端:根据现有存储库检查唯一值
  • 存储库(例如数据库):设置唯一约束
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.