Should server side dto validation validate the existance of data or the integrity?

169 Views Asked by At

So far I have always validated my dto`s properties for existing values, min, max, length etc..

Now I have a usecase with my http api where the payload of a http post contains Ids (database foreign keys) which either does not exist in the database or these ids does not belong to the userId inside the bearer token. UserId is always a field in each table.

Should I really write a repository Method like:

// done with 3 queries still room for optimization...
    public bool NewTestTypeIsValid(string userId,int schoolyearId, int schoolclassId, int subjectId)
    {
       return context.TestTypes.SingleOrDefault(x => x.userId == userId && x.schoolyearId == schoolyearId) != null &&
              context.Schoolclasses.SingleOrDefault(x => x.userId == userId && x.schoolclassId == schoolclassId) != null &&
              context.Subjects.SingleOrDefault(x =>x.userId == userId && x.subjectId == subjectId) != null;
    }

to check wether the the http post for a test type is valid/invalid and return a 400 bad data if invalid?

In order to make the question more hard to answer I present a more real life sample:

When this data is http posted to the server I would not only have to validate the subjectId, schoolclassId, schoolyearId but also each TestTypeId

of an updated TestType

The data is not coming from a REST endpoint its very soap style which I just need :-)

 public async Task<IEnumerable<TestType>> SaveTestTypesAsync(List<TestType> testTypes, int schoolyearId, int schoolclassId, int subjectId, string userId)
        {
            var testTypesFromDatabase = await context.TestTypes
                                          .Include(t => t.Subject)
                                          .Include(s => s.Schoolclass)
                                          .Where(p =>
                                          p.Schoolclass.Id == schoolclassId &&
                                          p.Subject.Id == subjectId && p.UserId == userId
                                          )
                                          .AsNoTracking()
                                          .ToListAsync();

            var schoolclass = new Schoolclass { Id = schoolclassId };
            var subject = new Subject { Id = subjectId };
            var schoolyear = new Schoolyear { Id = schoolyearId };

            // Make the navigation properties available during SaveChanges()
            context.Attach(schoolclass);
            context.Attach(subject);
            context.Attach(schoolyear);

            // DELETE
            var testTypesToRemove = testTypesFromDatabase.Except(testTypes, new TestTypeComparer()).ToList();
            context.TestTypes.RemoveRange(testTypesToRemove);

            // ADD
            var testTypesToAdd = testTypes.Where(t => t.Id == 0).ToList();  // 
            foreach (var testType in testTypesToAdd)
            {
                testType.Schoolclass = schoolclass;
                testType.Subject = subject;
                testType.Schoolyear = schoolyear;
            }
            context.TestTypes.AddRange(testTypesToAdd);

            // UPDATE
            var modifiedTestTypesToUpdate = testTypes.Except(testTypesToAdd.Concat(testTypesToRemove).ToList(), new TestTypeComparer()).ToList();
            foreach (var testType in modifiedTestTypesToUpdate)
            {
                testType.Schoolclass = schoolclass;
                testType.Subject = subject;
                testType.Schoolyear = schoolyear;
            }
            context.UpdateRange(modifiedTestTypesToUpdate);           
            await context.SaveChangesAsync(); 

return await this.GetTestTypesConfigurationAsync(schoolclassId, subjectId, userId);
        }
0

There are 0 best solutions below