Elisabeth
Elisabeth

Reputation: 21216

Validate a Create and Edit DTO with nealy all same properties

I have too very similar DTOs.

They differ only in the one property which identifies the Test resouce.

When I create now instead a EditAddTestDTO and make the

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

Then I can not put the RequireAttribute on it because it would not work in the Create-Scenario where I have not the TestId obviously.

How do you solve that problem?

Create 2 DTO`s as I already have or 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; }
}

Upvotes: 0

Views: 818

Answers (2)

pmccloghrylaing
pmccloghrylaing

Reputation: 1129

I would avoid sharing a base class. There's no logic you're trying to share between the classes so keep them clean and simple.

If you want to use some of the same code for both models add an interface instead and have the two classes implement it. This has the advantage that the interface can be defined in a different project with any services that use it.

EDIT:

You could have something like this, assuming you only need read access in your service, but it really depends what properties you need access to:

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

The nullable TestId allows you to differentiate between edit and create in your service.

Upvotes: 2

kamil-mrzyglod
kamil-mrzyglod

Reputation: 5008

You can create an abstract class TestDTO which contains all necessary properties(but I believe my edited answer is better that creating all those abstraction stuff):

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

And then just implement properties in your others DTOs or just place those properties in your CreateTestDTO and just derive from it in EditTestDTO adding TestId property.

EDIT:

Then you can have following 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; }

}

Another approach would be validating your model using IValidatableObject interface and adding a flag, which can be used during validation:

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();
          }
      }
   }
}

Upvotes: 0

Related Questions