使用几乎所有相同的属性验证创建和编辑 DTO

Validate a Create and Edit DTO with nealy all same properties

我有太多非常相似的 DTO。

它们的区别仅在于 属性 标识测试资源。

当我现在创建一个 EditAddTestDTO 并制作

public int<Nullable> TestId {get;set;}

然后我不能在上面放置 RequireAttribute,因为它在我显然没有 TestId 的 Create-Scenario 中不起作用。

你是怎么解决这个问题的?

创建 2 个我已有的 DTO 或 AddEditBaseDTO?

public class EditTestDTO
{        
    [Required]
    public DateTime Date { get; set; }
    [Required]
    public int Number { get; set; }
    [Required]
    public int SchoolclassCodeId { get; set; }
    [Required]
    public int SchoolyearId { get; set; }
    [Required]
    public int TestTypeId { get; set; }
    [Required]
    public int TestId { get; set; }
}

public class CreateTestDTO
{
    [Required]
    public DateTime Date { get; set; }
    [Required]
    public int Number { get; set; }
    [Required]
    public int SchoolclassCodeId { get; set; }
    [Required]
    public int SchoolyearId { get; set; }
    [Required]
    public int TestTypeId { get; set; }
}

您可以创建一个包含所有必要属性的抽象 class TestDTO(但我相信我编辑的答案比创建所有这些抽象内容更好):

public abstract class TestDTO
{

   public abstract DateTime Date { get; set; }

   public abstract int Number { get; set; }

   public abstract int SchoolclassCodeId { get; set; }

   public abstract int SchoolyearId { get; set; }

   public abstract int TestTypeId { get; set; }
}

然后只需在您的其他 DTO 中实现属性,或者将这些属性放在您的 CreateTestDTO 中,然后在 EditTestDTO 中派生并添加 TestId 属性。

编辑:

那么你可以有以下classes:

public class CreateTestDTO : TestDTO
{
   [Required]
   public DateTime Date { get; set; }
   [Required]
   public int Number { get; set; }
   [Required]
   public int SchoolclassCodeId { get; set; }
   [Required]
   public int SchoolyearId { get; set; }
   [Required]
   public int TestTypeId { get; set; }

}

public class EditTestDTO : TestDTO
{        
   [Required]
   public DateTime Date { get; set; }
   [Required]
   public int Number { get; set; }
   [Required]
   public int SchoolclassCodeId { get; set; }
   [Required]
   public int SchoolyearId { get; set; }
   [Required]
   public int TestTypeId { get; set; }
   [Required]
   public int TestId { get; set; }

}

另一种方法是使用 IValidatableObject 接口验证您的模型并添加一个标志,该标志可在验证期间使用:

public class EditTestDTO : IValidatableObject
{        
   [Required]
   public DateTime Date { get; set; }
   [Required]
   public int Number { get; set; }
   [Required]
   public int SchoolclassCodeId { get; set; }
   [Required]
   public int SchoolyearId { get; set; }
   [Required]
   public int TestTypeId { get; set; }

   public int? TestId { get; set; }

   public bool IsEdit {get;set;}

   public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
   {
      if(IsEdit) 
      {
          if(!TestId.HasValue)
          {
              yield return new ValidationResult();
          }
      }
   }
}

我会避免共享一个基地 class。您试图在 class 之间共享任何逻辑,因此请保持它们简洁明了。

如果您想对两个模型使用一些相同的代码,请改为添加一个接口并让两个 classes 实现它。这样做的好处是可以在使用它的任何服务的不同项目中定义该接口。

编辑:

你可能有这样的东西,假设你只需要在你的服务中读取访问权限,但这实际上取决于你需要访问哪些属性:

public interface ITestDTO
{
    DateTime Date { get; }
    int Number { get; }
    int SchoolClassCodeId { get; }
    int SchoolYearId { get; }
    int TestTypeId { get; }
    int? TestId { get; }
}

public class EditTestDTO : ITestDTO
{
    [Required]
    public DateTime Date { get; set; }
    [Required]
    public int Number { get; set; }
    [Required]
    public int SchoolClassCodeId { get; set; }
    [Required]
    public int SchoolYearId { get; set; }
    [Required]
    public int TestTypeId { get; set; }
    [Required]
    public int TestId { get; set; }

    int? ITestDTO.TestId { get { return TestId; } }
}

public class CreateTestDTO : ITestDTO
{
    [Required]
    public DateTime Date { get; set; }
    [Required]
    public int Number { get; set; }
    [Required]
    public int SchoolClassCodeId { get; set; }
    [Required]
    public int SchoolYearId { get; set; }
    [Required]
    public int TestTypeId { get; set; }

    int? ITestDTO.TestId { get { return null; } }
}

可为空的 TestId 允许您在服务中区分编辑和创建。