Where to validate user input in a program?
Let's say I have to implement a program for a small clinic company that allows its users(this is, the doctors) to schedule consults, log clients medical histories, etc. So, this will probably be the standard 3-layer application: Presentation, Controller and a Data Layer (that'll connect to a database).
I see 3 possibilities:
My first idea was to put the validating code right in the Domain Layer. But I feel that then I might be tempted to do the checking on class A, then the same check on B that uses A, then on C that uses B, etc. It on the other hand is good as it is开发者_如何学C easy to unit-test the validation logic.
There's a second school of thought that'll say that the best place to validate user input is as soon as possible, i.e., probably on the Presentation Layer (or in the Controller). This seems like a good idea, generally. If on the Controller, it will probably be easy to unit-test, too. It also allows one to switch the Views or the Data Layer and still have everything right.
Try to put the most validating logic possible on the database itself. This seems like a good idea, as it enforces that no data corrupts the database. The problem I see is that if I want to use different data repositories, I'll have to data validation logic again for the new one. Having that kind of logic at the Domain Layer, for example, would not have this problem.
How do you generally approach this problem?
As you've noted, there's more than one place to validate data.
There are also several levels of validation:
- Correct format and type; all required values present (e.g., if date of birth is required, make sure it appears and is of type Date; if it's a String, make sure it conforms to the expected format such as 'yyyy-MM-dd')
- Level 1 plus "business correctness": completed transaction is valid against your business rules (e.g., "date of birth must be at least eighteen years earlier than today").
There's a school of thought that says you should consider all of them:
- Validation on the client to ensure the best experience for users. Don't make them wait for a round trip to the server to find out something's wrong. Put a JavaScript validation in place that will tell them the level 1 validity right away.
- Validate again on the server side, because your service layer might not have a user interface in front of it. Bind and validate all values coming into your service tier.
- Perform all level 2 validations as part of the transaction in the service layer. Make sure that inputs are correct from a business point of view.
- If the database is shared by more than one application, put business logic into constraints, stored procedures, and triggers to ensure data integrity.
I don't think these should be "either or" decisions.
Do not mix up "when" and "where".
"When" should be as early as possible, maybe triggered by the presetation layer.
"Where" should be close to the domain logic.
In conjunction this e.g. could mean to have the presentation layer calling a verification service offered by the domain logic.
You often need to do the valiation at several layers:
- The client layer to ensure that the user experience is as good as in can be. For example avoiding inputing 10's of fields and then having to start over again due to invalid input.
- At the service layer, since you are not 100% sure that the request has been processed by the client (may be some one has sent a message directly to the service layer.
- At the service layer because some things cannot be checked on the client.
The good news is that some technologies allow you to specify the validation rules once and they will generate validation code for both the client and the server. See http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx This helps for the first 2 cases above.
精彩评论