I have the action contlrSaveText() in controller and the method modelSaveText() in model.
When the data comes from the website to the contlrSaveText(), I check whether the required information is received to save text, i.e. text name, text content etc. Then I call modelSaveText() to actually perform saving text. Do I need to validate data in this method as well or I can expect that controlled already did the job?
A model is only an abstract description, while a controller does the work.
Your model might have a controller on its own that take care of the data and updates the model. But that is technically a controller.
How he works with toward the outside, e.g. another controller that fills data in, is up to you how you define the interface. If your model uses relations or properties that require to be set up by the controller then you have to validate the data before inserting/accepting. But if not, then there is no point in validation and it can be skipped for performance reasons.
If you need to reject invalid data you have to think of a way how to tell the outside what whent wrong so it can respond to the error.
In your example I would go for validation, but that is just my opinion.
Related
I'm designing an application trying to follow the REST spec. I'm trying to figure out the best way to design it.
So let's say I'm doing a POST call that so I have a "post" method in my controller and model
// in controller
function post()
{
//call post model here
}
In my post request I need to make the following checks:
-validate fields
-make sure item name is unique for that user
-make sure there are less than 10 items
-etc (there could be more cases)
Now in controller post function I will return a REST message and status code based on whatever happens, which is fine, but I'm curious to know where it's better to keep all those checks.
I can put all the checks in the model and then return some kind of array like:
array('text' => 'return response text/array or whatever here', 'code' => '200/400/etc')
Then just return this in the controller, or is it better to break up those checks into individual functions within the model and then do all the checks in the controller?
// in controller
function post()
{
//if validation fails -> send response
//if name is not unique -> send response
//etc...
}
From a design point of view, if I ever wanted to potentially call the "post" method in the project model from other methods, it would not have an all encompassing function to handle it, however if I do keep it all in one model function it doesn't give me a lot of reusability. If I had to pick sides, chances are I probably wouldn't need to reuse those "check functions" too much anyway, however it also seems weird to have all that response info in the model rather than the controller.
Can anyone please give me some input on this.
I would not create post method inside the model (although having it in the controller is perfectly fine) simply because you just put code/model in such a frame that is not re-usable plus less readable. For instance, instead of post method in the model I would create create method.
There is no one-fits-all way for data validation. I like creating validation classes which have only one method validate for various data types (e.g. username validation class checks if it matches regex and is unique). It's better than copy pasting the validation code to every action (DRY). Where to call this class method? It depends. You can simply call that it in the action. Since the validation code is inside the validation class, it will look alright. You can also create a mapper which takes the request, determines what validations have to be performed and etc. but it might be overkill and is hard to do properly (maintainability wise).
For output again - DRY. It depends on what MVC framework are you using and there might be a good solution for this already. If not, you can create a class for that (yup, I am DRY maniac). You pass response code, array (or string) with response and class nicely wraps everything into JSON, XML format. Advantages: if you change then output format then you need to change only in one place.
Also consider using Remote Facade pattern.
Hopefully, you found something useful in this post.
I would separate the API from the MVC application and use Apify
I'm really confused by this... still.
I asked a similar question to this a while before, but i'll ask it even simpler now.
I see this in a lot of samples and tutorials. How could you put [Bind(Exclude="ID")] on an entire Model, and expect to do Edits on the model? If you get pack all the properties of a model on a POST but not the ID, then how do you know which ID to edit?
Even if i'm using ViewModels... i'm probably creating them without IDs. So in that case... also... how do I know which ID was updated on an Edit?
Yes, i understand that there is a "security" element to this. People can hijack the ID... so we need to keep people from updating the value during a POST. But... what is the correct way to handle edits then? What's common practice?
I feel like i'm missing something VERY trivial.
In MVC requests are processed by the model binder when the client makes a request. If you include models on your controllers then, as far as I'm aware, you actually have to specify the model you wish to bind to by prefixing your arguments with the model name (unless you only have one argument which is the model)
SomeModel_ID
Now, in some cases you might want to exclude certain properties from being bound to because they pose a security risk, which you seem to be happy with as a concept. We will exclude ID on the model, preventing any client request from posting this value in plain text.
Now why might we exclude an entire model? Well not all controller arguments are pre-processed by a model binder. RedirectToAction for example does not pass through the model binder, so it is conceivable in this instance for you to create a new model in a POST controller action, and redirect to a GET controller action, passing along a sanitised model. That model cannot be populated by the client, but we are free to populate it ourselves on the server side.
The only time I bind to a model is when I have a view model and an associated editor for that model. This makes it really easy to inject a common editor into a page and to encapsulate those properties. If you have to exclude certain properties from being bound to I would argue that you are doing it wrong.
Update
Following your comments I think I can see why you might be confused. The model bind excluder prevents the client from ever setting a model property. If you need this property to do your updating then you simply can't exclude it. What this does mean then is that the user could potentially post back any ID. In this case you should check that the user has permission to be modifying any objects or database records associated with this ID before serving the requested update. Validating the arguments is a manual process. You can use data annotations for validating inputs, but this isn't likely to help very much with access permissions. It's something you should be checking for manually at some stage.
You know the ID because it's passed to you through the page address. So:
http://yoursite.com/admin/users/edit/20
Will populate your ID parameter with 20. If it's used in a POST (ie, the information is filled in), just manually fill in the ID field and pass it to the database controller in whatever manner you have devised.
This is also immune to (trivial) hijacks because if they were to write some other ID besides 20, they wouldn't be updating the user with ID 20 now would they? :)
Suppose, as part of an iphone application, I need to show user a list of some of some objects.
The model
Represents actual objects to be shown
Brainless data, collection of getters and setters
The view
Displays the list, passes received actions to a controller
Presentation layer
The Controller
Interprets actions received from the view and takes actions on data
Sits between the view and data
In this picture, would be be controller's responsibility to persist model to disk, or, should it be a part of Model's logic? Request to do this will come from a controller, but, should the controller know how to save data to disk, or should data know how to save itself to disk?
This is wrong.
Model is responsible for all the business logic. Additionally model is not directly aware of database or any other data storage medium. When model is initialized it receives factory for creating DAOs or DataMappers which are the ones responsible for storing and retrieving the informations.
Controller interprets the received information from view , and changes the state of model and view.
View either receives information from a persistent model via observer pattern ( classical MVC ) or request data from models ( Model2 MVC ).
I can see this going both ways. I would think that this logic goes into the model this way the controller is a little cleaner. Also, if you're using this functionality across models and it's mostly consistent e.g $person->saveData(), $user->saveData() then you could possible extend the base model so it would be inherited by other models and save you from duplicate code.
If this logic is incorporated into the model it would probably be a good idea to make it flexible enough so that the controller can override the persisting of data. So maybe, pass an argument into the model function $person->save( false ) This false would prevent the model from persisting the data but on default would be true.
can anybody tell me, why communicates the model direct with the view in the MVC pattern, and why not just throught the controller?
http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
Sometimes it is too costly to use Controller for simple View/Model communication.
If your view just shows raw data without any operation (filtration, visualization, modification ...) it is easy to forget about Controller.
But this behavior is so abuse-able sometimes it kills all of the advantages of MVC.
And this where MVP comes in:
MVP (Model-View-Presenter) cuts the connection between model and view and every thing pass through man-in-the-middle (Presenter).
The views know of the model and will interact with the model.
If a button is clicked an action message might be sent to a model object in order to get
something done.
If a new value is typed into an entry field an update message might be sent to a model
object in order to give it its new value.
If a value is needed for a display an enquiry message might be sent to a model object in
order to get a value.
I'm using CakePHP but it's a question about the MVC pattern. I have in my form the input-text for the tags (separated by commas). To add the tags I've created a Tag model method that basically check if the tag exists and then add the new tag or just a new unit in the tag counter (the Tag model has these fields: id, name, slug, count).
In the controller I explode the tags field and pass one tag at a time.
The question is: where do I sanitize data? In the controller or in the model method? I think it should be in the controller because that's where I explode but in term of reusability I think I should sanitize data in the model.
What do you think?
You should sanitize your data on the View for client-side and Controller for the server-side.
I would say that, strictly speaking, sanitizing your data should occur in the controller, but sanitizing also generally refers to cleaning user input to avoid many issues, such as SQL injection. Since you're using the term "sanitize" in a different context, we have to pay more attention to what that context is.
You're not cleaning up user input, which means it doesn't really need to happen in the controller. You're changing the result of this action depending on whether or not the item you're saving already exists in the database. Therefore, in my mind, it should be happening in the model (or, as MunkiPhD specified, have a method in some sort of helper class that you can call from anywhere - but I say call it in the model).
Edit: Usually, in MVC, the model knows whether it's supposed to save a new row into the database or update an existing one based on whether or not your model instance has a valid ID. If it has an ID, the model should save to the row indexed by that ID. If it does not, the model creates a new one. It's my understanding that all you want to do is know where to make it decide whether to create a new one or update an existing one, and that happens in the model.
I disagree with sanitizing the data for storage in controller, and think the best place is to do it in model, as controller should not know how the data is stored, but sanitizing needs that knowledge (e.g. mysql_real_escape_string() for storing a MySql vs. pg_escape_string() for PostgresQL, or maybe checking for valid XML if stored in an XML file, or something else for different storage mechanisms).
To prevent things like cross site scripting, do not sanitize the data before storing, as you may have some legitimate use for some html tags later on, and do that (ideally) in view or in controller.
You'd want to sanitize it in from your controller, however, "from" doesn't mean "in." Have a separate class sanitize the data - that way you can call that class from wherever you need to.
You basically want to create the contract that your model will receive good data all the time, which means you'd have to sanitize it beforehand.