Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

View model validation vs domain model validation

Tags:

If client validation is done when is it necessary to do domain level validation?

I use ASP.NET MVC for my web applications. I like to distinguish between my domain models and view models. My domain models contain the data that comes from my database and my view models contain the data on my views/pages.

Lets say I am working with customer data.

I will have a table in my database called Customers.

I will have a customer class which could look something like this:

public class Customer
{
     public int Id { get; set; }

     public string FirstName { get; set; }

     public string LastName { get; set; }

     public DateTime DateOfBirth { get; set; }
}

And I will a create customer view model to represent only the data that I have on my view:

[Validator(typeof(CustomerCreateViewModelValidator))]
public class CustomerCreateViewModel
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     public DateTime DateOfBirth { get; set; }
}

I will have a create view that accepts my CustomerCreateViewModel and binds my input fields to my view model:

@model MyProject.ViewModels.Customers.CustomerCreateViewModel

@using (Html.BeginForm())
{
     <table>
          <tr>
               <td>
                    @Html.TextBoxFor(x => x.FirstName)
                    @Html.ValidationMessageFor(x => x.FirstName)
               </td>
          </tr>
          <tr>
               <td>
                    @Html.TextBoxFor(x => x.LastName)
                    @Html.ValidationMessageFor(x => x.LastName)
               </td>
          </tr>
     </table>

     <button id="SaveButton" type="submit">Save</button>
}

As you can see I have a CustomerCreateViewModelValidator that contains my validation rules. After the user has entered some data into the text boxes he will click the submit button. If some of the fields are empty then validation fails. If all the required fields are entered then validation succeeds. I will then map the data from my view model to my domain model like this:

Customer customer = Mapper.Map<Customer>(viewModel);

This customer domain model I take and pass it onto my repository layer and it adds the data to my table.

When does validation need to be done on a domain model? I do all my validation on my view model. I can validate my data in my domain model just before I add it to the database but seeing that it was validated on the view model wouldn't it be just replicating the same validation on the client side?

Could someone please share some light on this validation matter?

like image 633
Brendan Vogt Avatar asked Jul 18 '13 10:07

Brendan Vogt


People also ask

What are the two approaches of validation?

The three approaches are referred to as internal validation, external validation and process validation. There are three benefits of this framework. First, it aids both researchers and practitioners in identifying, analyzing and categorizing various methods that may be relevant to data validation.

How are domain models validated?

Implement validations in the domain model layer. Validations are usually implemented in domain entity constructors or in methods that can update the entity. There are multiple ways to implement validations, such as verifying data and raising exceptions if the validation fails.

What are the types of validation in MVC?

There are two types of validations: Server side Validations. Client Side Validations.

What is meant by model validation?

Model validation refers to the process of confirming that the model actually achieves its intended purpose. In most situations, this will involve confirmation that the model is predictive under the conditions of its intended use.


2 Answers

Always validate at both levels.

You need to validate the view models because you want to feed back to the user as quickly and easily as possible if they've done something wrong. You also don't want to be bothering the rest of your domain logic if the model is invalid.

But, you will also want to verify that everything's happy in the domain, once the view model has been validated. For simple models, these checks may be the same, and so it does look like duplicating logic, however as soon as your application grows so you may have multiple user interfaces, or many different applications using the same domain models, it becomes so important to check within the domain.

For example, if your application grows so you end up providing an API to customers to interact directly with the application programmatically, it becomes a necessity to validate the domain models, since you cannot guarantee that the user interface used has validated the data to the standard that you need (or even validated it at all). There is an argument to say that the data received by APIs should be validated in much the same way as the view models are validated, and that's probably a good idea since that is achieving the same goal as the view model validation is. But regardless of the route in (either from a UI or the API), you will want to always guarantee that the data is valid, so defining that in a central place is ideal.

The aims of the two levels of validation is different, too. I would expect a view model validation to inform me of all problems (such as missing first name, last name is too long, DoB is not a date). However, I think it would be ok for the domain logic to fail on the first error, and just report that one. Again, for simple models, it may be possible to collect all errors and report them all back, however the more complex an application gets, the harder it gets to anticipate all errors, especially if the logic will change depending on the data. But, as long as only good data gets past, that should be fine!

like image 60
Jamie Burns Avatar answered Sep 25 '22 08:09

Jamie Burns


As a general rule I consider the domain model to be the most important code and therefore management of its state holy. For that reason I would never assume for the domain model to be in a valid state just because it was operated on by a presentation layer that is supposed to enforce validity. This would mean your domain layer is tightly coupled to your presentation layer.

It is best to start thinking from the domain model outwards (onion architecture). The reasoning behind all this is that the domain model is the least likely to change over time and acts as a core to an application, insulating layers from each others' flaws.

So starting with a domain model that enforces its own validity you are left with the question of duplication of validation code. There are some ways to avoid this. Your view model may for example try to create a domain object and translate any exceptions thrown as validation failures. Validators can also be extracted and reused. Depending on your use-cases you have to see what works best for you. Just beware to keep it simple. Perhaps, if your use-cases are not to though, it might be most maintainable to simply duplicate the validation. Remember that deduplication increases complexity.

I have seen code bases in which only the domain layer handled the validation and codebases in which validation was handled in both the domain- and the presentation layer. I have a preference to simply duplicating the validation logic at this point, because I have seen how hard it is to meaningfully map domain validation errors well to a contextual user-interface.

like image 41
Lodewijk Bogaards Avatar answered Sep 25 '22 08:09

Lodewijk Bogaards