-2

I'm working on an ASP.NET Core application that requires handling multiple types of a single entity. Each type has its own properties and validation rules, which has led to confusion and complexity in managing DTOs, validations, and controllers.

  • I’m using ASP.NET Core with Entity Framework and want to create a clean and maintainable architecture.
  • Each entity type has distinct validation requirements that complicate the DTO and controller structure.

Specific Questions

  • What are the best practices for creating and managing different DTOs for multiple entity types?
  • How should I approach validations to ensure they are both clear and efficient?
  • What design patterns or strategies can I implement to keep my controllers organized and manageable when dealing with multiple entity types?

I would appreciate any guidance, examples, or resources that can help me tackle this challenge effectively.

12
  • 2
    I don’t understand what you mean with “multiple types of a single entity”. An example would probably help.
    – Rik D
    CommentedOct 13, 2024 at 7:17
  • How do you feel about my answer to your previous question on this topic?
    – Ewan
    CommentedOct 13, 2024 at 10:10
  • @Ewan Yeah, I get it, but I don't know how to ignore the data when I still need to perform validation and other tasks.CommentedOct 13, 2024 at 11:44
  • @RikD I have entities like User, which has subclasses like Teacher, Student, etc., and Question, which has subclasses like MCQ, Essay, etc. Each type has its data that I need to validate in different ways.CommentedOct 13, 2024 at 11:46
  • @MarkoSami how do you mean? like in my example, since each action on a controller has different validation logic, you make a ValidationService object for each with the rules in and call its Validate(object) method. all your controllers will look the same, you can use global error handling and custom exceptions to get rid of try catch throws everywhere
    – Ewan
    CommentedOct 13, 2024 at 13:14

1 Answer 1

0

If I understand you right you have the following classes:

Question MultipleChoiceQuestion : Question Essay : Question .... : Question 

And you want a single Create endpoint:

Post Create(Question q) 

Which will validate and save to a database any of the derived Question types.

First off, .NET won't magically know which derived type to deserialise the incoming JSON to. You'll need to add some cleverness type discriminators.

This needs some $type field in the JSON, so:

Question { public string Type => this.getType().ToString(); // I'm sure you can do better. } 

Now that you have the actual type in the controller you just need to select the validation logic. Given my previous answer where I stress the benefits of keeping the validation separate from the object, we want to avoid question.Validate().

QuestionController { [HttpPost] public Task Create(Question q) { IValidator v; if(!this.ValidationDictionary.TryGetValue(q.Type + "_Create", out v)) { throw new CantFindValidatorException(q.Type); } v.Validate(q); // throw validation exception with collection of error messages. handle in global exception handler which just converts to json and adds error code of your choice. this.repo.Add(q); //more looking at q.Type to decide which tables to put it in. } } 

Given the fiddlyness of this and the need to check the type in multiple places and ensure its sent in the JSON, You have to consider the alternative of just adding extra controller actions:

QuestionController { [HttpPost] public Task CreateEssay(Essay q) { this.create(q); } [HttpPost] public Task CreateMCQ(MultipleChoiceQuestion q) { this.create(q); } private Task create(Question q) { IValidator v; if(!this.ValidationDictionary.TryGetValue(q.GetType(), out v)) { throw new CantFindValidatorException(q.GetType() + "_Create"); } v.Validate(q); select q.GetType() //or factory pattern of choice case "Essay" this.repo.AddEssay(q); ... } } 

This approach levers the built in serialisation and route mapping.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.