Best Place for Validation in Model/View/Controller Model?

30,329

Solution 1

If you're validating the data on client side (i.e Javascript validation) which is absolutely not enough and not secure at all, You should implement it in View.

If you're validating data on server side, And your validation does not require application business logic (i.e you're not checking to see if the user has enough credit in his account), You should validate in the controller.

If the validation requires business logic, Implement it inside the model and call it via controller.

Postback validation is not good since it puts lots of pressure and delay, And the only advantage is to the programmer (not to be accounted).

You can use regex for most of validation, Which has the same syntax (almost) on PHP and JS.

Solution 2

The right place for validation is the Model.

This makes most sense because you are doing validation on the data, which is what the model represents. In terms of the CRUD updates, the model should always be used somehow.

  • If you are changing data from the view, you should have validations being checked.

  • If you have controllers changing data, you should have validations being checked.

  • And finally if you have having the model itself changing data, you should still have validations.

The only way to achieve this state is to have the validation go into the model.

Due to performance and faster response, after implementing the validations in the model, you should try to add some sort of client side(JS) to immediately notify the end user.

Validation is always about the data. Why are you validating data? So you can keep the integrity of the information your storing. Having the validations at the model level allows data to theoretically be always correct. This is always a neccesity. From there you can add extra validations in your business logic and client side to make your application more user friendly.

Solution 3

Don’t get confuse with sanitizing or cleaning the posted value with validation. You should fetch the posted values and scrub them by removing any malicious elements from the values within the Controller. Then send the data to the Model to be validated for the expected values or format. By breaking those actions into two procedures reduce the risk of malicious code to get implemented. This method works well if you are using the “trust no one input” policy; knowing some programmers can become sloppy or lazy. Another positive side is preventing your Model from becoming bloated and over worked, if so, then use a model helper to do the dirty work. This approach will also help balance your application load and improve performance.

Solution 4

Validation in the model seems to be the most common approach (you end up with something like $obj->isValid()) and this is suitable in many situations.

However, depending on your use case there may be good reasons to perform validation outside the model, either using separate validation code or in the controller, etc.:

  • If much of the overall validation problem involves information not accessible to the model (for example, if an admin user can perform transformations that a regular user cannot, or certain properties cannot be changed after a certain date), then you might want to check all these constraints in the same place.
  • It may also be convenient or necessary to apply very lax validation rules when constructing objects for tests. (A "shopping basket" object might ordinarily require an associated user, who in turn requires a valid email address, etc. A 100% valid shopping basket object might be inconvenient to construct in shopping basket unit tests.)
  • For historical reasons, validation rules might change (e.g. enforcing a "gender" where previously none was necessary) and so you may end up with different versions of data that need to be treated differently. (Different validation rules may also apply to bulk data import.)
  • If validation is very complex, you might want to provide different error messages (or none at all) depending upon what's most useful to the caller. In other situations, true or false might be all that is necessary.

It may be possible to handle these different use cases via arguments to the model's isValid() method, but this becomes increasingly unwieldy as the number of validation styles increases. (And I do think it's almost guaranteed that a single "one size fits all" isValid() method will eventually prove insufficient for most non-trivial projects.)

Share:
30,329
Lea Hayes
Author by

Lea Hayes

I have been fascinated by software and video games since a young age when I was given my first computer, a Dragon 32. Since then I have experimented with numerous methods of development ranging from point-and-click type packages to C++. I soon realized that software development was what I wanted to do. Having invested a lot of time into programming with various languages and technologies I now find it quite easy to pickup new ideas and methodologies. I relish learning new ideas and concepts. Throughout my life I have dabbled in game and engine development. I was awarded a first for the degree "BEng Games and Entertainment Systems Software Engineering" at the University of Greenwich. It was good to finally experience video games from a more professional perspective. Due to various family difficulties I was unable to immediately pursue any sort of software development career. This didn't stop me from dabbling though! Since then I formed a company to focus upon client projects. Up until now the company has primarily dealt with website design and development. I have since decided that it would be fun to go back to my roots and develop games and tools that other developers can use for their games. We have recently released our first game on iPhone/iPad called "Munchy Bunny!" (see: View in app store). We hope to expand the game and release to additional platforms. Also, check out our tile system extension for Unity! (see: View product info)

Updated on July 09, 2022

Comments

  • Lea Hayes
    Lea Hayes almost 2 years

    I am working on a PHP project which makes extensive use of the MVC design pattern. I am looking to add validation to a form and am curious as to what the right place for validation is.

    Due to the way that forms are generated, validation on postback data is a lot simpler and less repetitive in view components. Is it acceptable to have the view validating response data, or should this be implemented within the controller, or even the model?

    What are the benefits?

  • dqhendricks
    dqhendricks about 13 years
    I was taught to make controllers light as possible. Seems to me that validation IS part of the business logic...
  • Lea Hayes
    Lea Hayes about 13 years
    Thanks for the responses, they are much appreciated.There are various kinds of forms, but as an example, a member sign up form where the various inputs are validated server-side to ensure both correctness and a unique username. Invalid inputs are to be highlighted with a CSS class.
  • AbiusX
    AbiusX about 13 years
    As in your example, duplicate usernames are part of application logic. But invalid characters in username could be checked at controller.
  • AbiusX
    AbiusX about 13 years
    controllers should be light, but since validation is mandatory, it can't be skipped. Lightening controllers means not putting any logic or view in it.
  • Neil McGuigan
    Neil McGuigan about 12 years
    this is what Yii does, and it works well. They also have "validation scenarios" so you can have different validation rules for different scenarios, such as create vs update
  • Lea Hayes
    Lea Hayes about 12 years
    It has been a while since I posted this question, but I have learnt from experience that it is easier to maintain the model by splitting it into two separate parts. The business model layer should apply all "business" rules like enforcing "gender" where it was previously not required. The business model can be altered to require "gender" on all new applications/updates/etc. The service model layer does not care about "business" rules but instead must validate data integrity, etc. Thus the service layer and the business layer can be tested independently. I write about this in my blog...
  • Lea Hayes
    Lea Hayes about 12 years
  • avgvstvs
    avgvstvs about 12 years
    Regex is only valuable if you first canonicalize input data, and escape for the apprpriate contexts that the data will be used in the view. (i.e., url/javascript escaping/encoding.) In most people's usage, regex isn't good enough.
  • tereško
    tereško about 11 years
    Controllers in MVC are part of presentation layer. They should not have any clue about how to perform data validation, that is a responsibility of model layer.
  • Salman Virk
    Salman Virk about 11 years
    If there is no difference between 'Application Logic'/'Use Story' and 'Domain Model', then putting validation in the Model looks practical to me. Otherwise, AbiusX's suggestion to put in Application Controller makes more sense. The issue is 'Application Controller' and 'GUI Controller' are different concepts. In short, the architectural decisions should determine the answer of this question.
  • AbiusX
    AbiusX about 11 years
    Its not like that. You mean that the UI should not be able to tell the user if they have typed a name instead of a number? It has nothing to do with the business logic of the application. It's more of a presentation matter. An Email input is a presentation matter, not a business logic matter (can be re-checked there too)
  • edsioufi
    edsioufi over 10 years
    Couldn't agree more with this answer. This design aspect is a subset of the anemic vs. rich domain model discussion. And this particular example is probably one of the best to point out why anemic domain models directly violate DRY, in a practical way (and not only theoretically, as anemic advocates often point out)
  • cSteusloff
    cSteusloff over 6 years
    If you use a relation database. create contains in the database, which map the core business logic.