I've been working with the MVC pattern for a while now, but I honestly don't feel like I truly understand how to work with and apply the "Model" ... I mean, one could easily get away with using only the Controller and View and be just fine.
I understand the concept of the Model, but I just don't feel comfortable applying it within the pattern... I use the MVC pattern within .NET and also Wheels for ColdFusion.
"the Model represents the information (the data) of the application and the business rules used to manipulate the data" - yes, I get that... but I just don't really understand how to apply that. It's easier to route calls to the Controller and have the Controller call the database, organize the data and then make it available to the View. I hope someone understands where my confusion resides...
I appreciate your help in advance!
Look at it like this. When your client requests a page this is what happens (massively trimmed):
He ends up at your controller
The controller gets the necessary data from your model
The controller then passes the data to the view which will create your HTML
The controller sends the HTML back to the client
So client -> controller -> model -> controller -> view -> controller -> client
So what is the model? It is everything that is required to get the data required for you view!
It is services
It is data access
It is queries
It is object mapping
It is critical 'throw exception' style validation
Your controller should not be writing your queries if you are sticking to the pattern. Your controller should be getting the correct data required to render the correct view.
It is acceptable for your controller to do a few other things such as validating posted data or some if/else logic but not querying data - merely calling services (in your model area) to get the data required for your view.
I suppose it's just what you decide to call the different bits in your application. Whichever class you use to pass information from the Controller to the View can be seen as/called "The Model".
Typically we call Model our entity classes, and we call View Model the "helper" classes, for lack of a better word, we use when a "pure" entity (i.e., one that will be stored in the database) doesn't suffice to display all the information we need in a View, but it is all mostly a naming thing.
Your model classes shouldn't have any functions; ideally a model class will have only properties. You should see model classes as data containers, information transporters. Other than that they are (mainly) "dumb" objects:
// This would be a model class representing a User
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
How do you actually pass information (whatever that might mean in your context) form your controller to your View and vice versa? Well then, that's your model. :)
Here is the way I have explained before:
Controller: determines what files get executed, included, etc and passes user input (if any exists) to those files.
View: anything that is used to display output to user.
Model: everything else.
Hope that helps.
Model is the code representation of your base Objects. While some less data-intensive systems may be light on the model end of MVC, I am sure you will always find an applicable use.
Let's take a contrived (but realistic) example to the usefulness of a model:
Say I am making a Blog. My Blog has Post objects. Now, Posts are used in and around the site, and are added by many users in the system. Our system was coded for people to enter HTML into their posts, but low and behold, people are starting to add pasted text. This text uses "\n" as the newline character.
With a model, this is a relatively simple fix. We simply make a getter that overrides postText:
public function get postText() {
return this.postText.replace("\n", "<br />");
}
Suddenly, we can affect behavior across the entire site with a few lines of simple code. Without the implementation of a model, we would need to find and add similar functionality where ever postText is used.
The Model in MVC is all about encapsulation and flexibility of a codebase as it evolves over time. The more you work with it and think about it in this manner, the more you will discover other cases that would have been a nightmare otherwise.
--EDIT (you have added to your question above):
Let us take this same example and use your Controller calling the database. We have 9 Controller classes for vaious pages/systems that use Post objects. It is decided that our Post table needs to now have a delete_fl. We no longer want to load posts with delete_fl = 1.
With our Post model properly implemented, we simply edit the loadPosts() method, instead of hunting down all the cases across the site.
An important realization is that in any major system, the Model is more of a collection of files than a single monolith. Typically you will have a Model file for each of your database tables. User, Post, etc.
model: word, sentence, paragraph
controller: for (word in sentence), blah blah... return paragraph
view: <div>paragraph.text</div>
The idea is to separate the concerns. Why not just have the controller logic in the view as well? The model represents the business objects, the controller manipulates those objects to perform some kind of task and the view presents the result. That way, you can swap an entire view for a different one and you don't have to rewrite the entire application. You can also have people work on different layers (model, controller, view) without affecting the other layers to a significant degree.
By combining the controller and the model, you are making your code less maintainable and extensible. You are basically not performing object-oriented programming as you are not representing the things in your database as objects, you are just taking the data out and sending it to the view.
The model contains business logic (i.e. significant algorithms) and persistence interaction - usually with a database. The controller is the MVC framework: Wheels, Struts, .NET's MVC approach. The view displays data that the controller retrieves from the model.
The big idea going on with MVC is that the view and model should be unaware of the controller - i.e. no coupling. In practice there's at least some coupling that goes on, but when well done should be minimal, such that it allows for changing the controller with low effort.
So what should be happening is a request hits the controller, typically a front controller, where there should be some glue code that you've written that either extends some controller object or follows some naming convention. This glue code has the responsibility for calling methods on the correct service layer object(s), packing that data inside of some sort of helper - typically an Event object - and sending that to the correct view. The view then unpacks data from the Event object and displays accordingly.
And when done well, this leads to a domain model (a.k.a. model) that is unit testable. The reason for this is that you've divorced the algorithms from any framework or view dependencies. Such that you can validate those independently.
Related
With MVC3, should I design my view models such that there is one that is bound to the view (DisplayModel), and one that is posted back to the controller (EditModel)?
To clarify, I am not asking about data models vs. view models -- I know it's not good to bind my views/controllers to data/domain models.
Nor am I asking about sharing one model across two separate views, one view that is used for displaying the data, and another view that is used for editing the data.
Rather, I am asking about one view that is used for editing data, and the model that is bound to the view vs. the model that is bound to the controller action.
In other words, if this is my view:
#model MyApp.Models.CustomerModel
Should my controller action look like:
public ActionResult Index(CustomerModel model)
Or:
public ActionResult Index(CustomerEditModel model)
At one point, we were doing the latter (separate). But lately, we've started doing the former (shared).
The reason for this change was because:
With MVC3 unobtrusive validation, if I'm using DataAnnotations on my model for validation, this is needed in both models if they are separated (on the display model to map client-side validation, and on the edit model for server-side validation).
As our application matured, we realized that our display and edit models were 95% identical, with the exception of the select lists that were in our view models. We've now moved these to a shared class and are passing these in via the view now.
But I've seen some other discussions that point to having shared models for view/controller to be a bad idea, and that it violates separation of concerns.
Can someone help me understand the tradeoffs for these two approaches?
I've seen perfectly good arguments for and against, it just depends what works best for your application. There's no one size fits all approach that can be applied!
If you haven't read it Jimmy Bogard has written a very good post about how his team does MVC here, which covers this topic.
I agree with rich.okelly's answer that there's no right approach.
There are a couple of concerns I have with using one model, though.
It's going to be very to always use one model without having unneeded properties when the view needs to display a selectable list of objects. The model will need to have the list of objects as well as a property to accept the POSTed value the user chooses. These unneeded properties add a small amount of code clutter and overhead.
(One way around this is to have the model contain only selected ID and have HTML helpers to build the lists.)
Another concern is more related to security.
A common scenario is displaying information in a form that should be considered read-only.
In the case of a ViewModel and an EditModel, the EditModel will only contain properties that are expected to be POSTed, whereas the ViewModel will contain all of the properties.
For example, if a form displays a user's salary, a user will be able to POST a 'salary' and have it bound to the ViewModel's Salary property automatically by MVC.
At this point, something has to be done to ensure it doesn't end up in the database. It could be if/else logic, a Bind attribute, Automapper logic or something else, but the point is that it's a step that could be overlooked.
When considering the lifespan of an application, I like the explicitness of the EditModel over time.
These concerns don't mean that two models are good and one model is bad, but they should be considered when choosing a design.
If the properties are the same for display and edit view models I see no reason to have separate classes.
I think you'll find that it's hit or miss no matter what way you go but if you can take the path of easiest maintainability then you should do that. In my experience, having a single model is much easier to maintain, obviously, but it seems that there is always some business decision that is made that forces me to split the models. If you're in that 95% then I think you are in really good shape. Your application, from a maintainability perspective related to your models, will be easy to maintain. When a change comes along, you have one place to make that change, for the most part. The issue I always seem to run into is scaling business changes across multiple models. Copy/paste issues, or simply forgetting about some property somewhere, always seems to hurt me because of the multi-model issue.
we realized that our display and edit models were 95% identical, with the
exception of the select lists that were in our view models. We've now
moved these to a shared class and are passing these in via the view now.
Are they 95% identical in data and operations or only in data? Remember that classes encapsulate data and behavior.
If they are 95% similar in properties but have totally different operations you might benefit from splitting them in two classes. Or you might not :)
As others pointed out there is no one-size-fit-all answer and in your case it seems that one class is OK...but if you start noticing that the behavior on each of them is unrelated don't be afraid to rethink you approach.
No - one view model for both directions. Mixing it up is not only harder to follow, but one could easily inject invalid values into the page that then get automatically bound. I could overwrite your customerid (or create one) for example.
Inherit from a base view model if you must or don't rely on data annotations at all and use the fluent api on your model save.
A great link (somewhat unrelated but the auto map is nice)
edit
(sorry someone else previously posted this below I just realized)
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
Also
ASP.net MVC - One ViewModel per View or per Action?
You (IMHO) should be generally binding to your method specific VieWModel rather than a shared view model. You could get caught in a trap of missing properties, etc. but it may also work just fine for you.
Use auto mapper to go between both. Jimmy also has a nice AutoMap attribute when returning to the View. Going back the other way I would not use a CustomerModel in general as there may be fields required in there that are not coming from my say, create view. For example a customer id may be a required field and for a "create" action it won't be present. But - if you find in the most of your cases this to actually work for you, then there is no reason at all not to use it.
I've read that best practice dictates fats models, skinny controllers.
Models should contain business logic such as getting a list of customers based on parameters sent from a controller.
Controllers should contain just enough logic to invoke methods within a model to return to a view.
However I see many examples and tutorials where there is logic within the controller such as a query that accesses a db to get a list of products. I was under the impression that the logic should live in a method inside a model. The controller can then invoke this method, rather than containing the actual logic to query the database.
So if I have a ProductController I might have a Index action which returns an Index View, and I would have a ProductModel which would house my logic to display certain products based on a query string(which the ProductController would pass to said model). Right?
So if I have a ProductController I might have a Index action which returns an Index View, and I would have a ProductModel which would house my logic to display certain products based on a query string(which the ProductController would pass to said model). Right?
That is correct. As per the Model-view-controller architecture:
The model manages the behavior and data of the application domain,
responds to requests for information about its state (usually from the
view), and responds to instructions to change state (usually from the
controller). In event-driven systems, the model notifies observers
(usually views) when the information changes so that they can react.
The view renders the model into a form suitable for interaction,
typically a user interface element. Multiple views can exist for a
single model for different purposes. A viewport typically has a one to
one correspondence with a display surface and knows how to render to
it.
The controller receives user input and initiates a response by making
calls on model objects. A controller accepts input from the user and
instructs the model and viewport to perform actions based on that
input.
Keep the data-related queries and operations in the model; stuff as much as you can in there in accordance with DRY (Don't Repeat Yourself). Make the functions reusable as much as possible so they can be ported into various controllers and used throughout the application as necessary.
The view should contain little - if any - logic outside of view-specific work.
Your controller functions should invoke the model functions required to retrieve and manipulate data, and should be as "thin" as possible (as you pointed out). The smaller and less involved the controller, the easier it will be to add asynchronous features that "don't reboot the application" on the front-end, making for a better user experience. (If you are concerned about this, anyway!)
The Add Controller dialog box in VS 2010 has the option of adding a scaffold with CRUD functions into the controller. This should tell you quite a bit above how the ASP.NET MVC dev. team views this debate.
I was doing a code review today and seen that someone having a view model classes that besides of data contains different methods, like
GetTable, GetPdf, LoadSomeData etc.
I personally didn't like it, since prefer to have a "plain" view Model classes, containing only the properties and put logic either into Controller either additional Service.
But on review I was not possible to find good arguments for that.
What do you think, is it a good way (style) of having a logic in view Model classes? What are pros/cons?
EDIT: It was ASP.net MVC2 application.
EDIT: Example (just from head) of such code..
public ActionResult SomeAction()
{
var model = new ViewModel();
model.LoadSomethingFromSomething();
model.AnotherMethod();
return View(model);
}
The principal of separation of concerns and the single responsibility principal dictates that the only "logic" that should be contained in the view should be that which manipulates how the view displays the data. Everything else should be in the controller. Semantically the view does one thing - displays data, anything unrelated to displaying said data - i.e. manipulating data, formatting data, loading data, converting data etc. should be handled by the controller.
In the real world, we don't always have the luxury of idealism, but in the ideal world, that's the way it should be. The principal of least surprise says that code should be in the least surprising place to find it. If I (as a code maintainer) need to fix something, I need to be able to find it quickly - if it's not where logic dictates I would find it, it provides unnecessary hindrance to my completing my tasks quickly and efficiently.
If GetTable pertains to loading a table construct (i.e. an HTML table) for the view, then perhaps it is relevant, if we're talking about getting table data from a database, then it is not.
I used to subscribe to the idea of totally "dumb" models.. I.E ones that don't do ANYTHING. However after using that idea in practice I found it wasn't ideal. I now subscribe to the idea that viewModels should know about how to create themselves from other objects.
I.E.
public ActionResult SomeAction(int? id)
{
var serviceModel = _myService.Get(id ?? 0);
var model = new ViewModel(serviceModel);
return View(model);
}
Basically, rather than adding methods to your model, create several constructors that take in objects used in that view model's creation. This frees up your controllers & service from knowing anything about how the viewModel works (meaning there is no object mapping code cludging up everything).
Then, to get an object out of the viewModel, you can do the following:
[HttpPost]
public ActionResult SomeAction(ViewModel model)
{
_myService.Update(model.MapToServiceModel() );
return SomeAction(model.id);
}
Your question feels vague to me. When you say view model, do you mean a view specific model constructed from your domain's model that a view consumes? In that case, I agree the view model should be pretty simple overall. The view shouldn't have to "think" much (ideally, it shouldn't "think" at all). Calling methods from a view (that aren't defined in helpers), even branching in a view, is a code smell to me.
IMO, controllers should also be thin and light. I like the real bulk of my logic to be in my models and also in the data access layer. Just depending on what type of logic we are talking about.
I am wondering if it is a good idea or bad, placing things like a List of countries in ViewModel, for binding to a drop down list? For example on a site's Registration page.
I was under the impression that a ViewModel is supposed to represent an instance of the filled out form, but I think I may be wrong as I have seen other people put things like lists in their ViewModel.
Would it not be better to put it in a static class somewhere and called directly from the View?
Like CommonData.ListCountries(); and then using Lambda to convert to SelectList item list in the view Directly?
As you've realized there are a variety of ways to accomplish your goal. While the MVC design pattern encourages certain application organizations how you organize your models, views and controllers is ultimately a matter of preference.
Scott Allen discusses his preference for dealing with ASP.NET MVC drop down lists in a blog post. Scott uses an extension method to convert an enumerable of a complex type into an IEnumerable<SelectListItem> on his model. He then describes that upon post back ASP.NET MVC will not be returning the IEnumerable<SelectListItem> he sent to the view, but only the value the user selected. He then suggests that utilizing two models can simplify things.
This is a reasonable description of what I refer to as ViewModels and FormModels. A ViewModel carries the display data to the view and a FormModel is used for carrying collected data back to a controller action. To explain further:
ViewModels contain data that help render views. By organizing my ViewModels this way I can place all necessary information to render a particular view into an associated model. This prevents me from having to use ViewData for anything that's not truly temporary.
FormModels are used to gather user input. FormModels (almost) never contain references to other complex types and are made up of primitives, DateTimes, and strings.
In either case I have a hard rule to never reuse a model for a different view. Having your models closely aligned with the views used to render them makes your views easier to write. You don't have to worry about things like static methods because your models should be carrying data to their associated views in a form that is easy for them to render. Tools like AutoMapper can help "flatten" domain objects into models for display purposes.
For additional reading checkout: ASP.NET MVC terminology is tripping me up - why 'ViewModel'?
Whatever data your View needs, put it in the ViewModel.
The way i see it, once your view is going through the rendering process, it should have all the info it needs from the Model it is bound to.
If you start to use helper methods, then the View is "going back to the controller" in a sense. Extension/helper methods are fine for formatting, etc, but they should not call through the model.
Don't forget, you also have ViewData (basically HttpContext.Current.Items, lives for single request), which is a lightweight storage mechanism that can be used to share data across partial views (for example).
At the moment, i got quite badly fashioned view model.
Classes looks like this=>
public class AccountActionsForm
{
public Reader Reader { get; set; }
//something...
}
Problem is that Reader type comes from domain model (violation of SRP).
Basically, i'm looking for design tips (i.e. is it a good idea to split view model to inputs/outputs?) how to make my view model friction-less and developer friendly (i.e. - mapping should work automatically using controller base class)?
I'm aware of AutoMapper framework and i'm likely going to use it.
So, once more - what are common gotchas when trying to create proper view model? How to structure it? How mapping is done when there's a multiple domain object input necessary?
I'm confused about cases when view needs data from more than 1 aggregate root. I'm creating app which has entities like Library, Reader, BibliographicRecord etc.
In my case - at domain level, it makes no sense to group all those 3 types into LibraryReaderThatHasOrderedSomeBooks or whatnot, but view that should display list about ordered books for specific reader in specific library needs them all.
So - it seems fine to create view OrderedBooksList with OrderedBooksListModel view model underneath that holds LibraryOutput, ReaderOutput and BibliographicRecordOutput view models. Or even better - OrderedBooksListModel view model, that leverages flattening technique and has props like ReaderFirstName, LibraryName etc.
But that leads to mapping problems because there are more than one input.
It's not 1:1 relation anymore where i kick in one aggregate root only.
Does that mean my domain model is kind a wrong?
And what about view model fields that live purely on UI layer (i.e. enum that indicates checked tab)?
Is this what everyone does in such a cases?
FooBarViewData fbvd = new FooBarViewData();
fbvd.Foo = new Foo(){ A = "aaa"};
fbvd.Bar = new Bar(){ B = "bbb"};
return View(fbvd);
I'm not willing to do this=>
var fbvd = new FooBarViewData();
fbvd.FooOutput = _mapper.Map<Foo,FooOutput>(new Foo(){ A = "aaa"});
fbvd.BarOutput = _mapper.Map<Bar,BarOutput>(new Bar(){ B = "bbb"});
return View(fbvd);
Seems like a lot of writing. :)
Reading this at the moment. And this.
Ok. I thought about this issue a lot and yeah - adding another abstraction layer seems like a solution =>
So - in my mind this already works, now it's time for some toying.
ty Jimmy
It's tough to define all these, but here goes. We like to separate out what we call what the View sees from what the Controller builds. The View sees a flattened, brain-dead DTO-like object. We call this a View Model.
On the Controller side, we build up a rich graph of what's needed to build the View Model. This could be just a single aggregate root, or it could be a composition of several aggregate roots. All of these together combine into what we call the Presentation Model. Sometimes the Presentation Model is just our Persistence (Domain) Model, but sometimes it's a new object altogether. However, what we've found in practice is that if we need to build a composite Presentation Model, it tends to become a magnet for related behavior.
In your example, I'd create a ViewFooBarModel, and a ViewFooBarViewModel (or ViewFooBarModelDto). I can then talk about ViewFooBarModel in my controller, and then rely on mapping to flatten out what I need from this intermediate model with AutoMapper.
Here's one item that dawned on us after we had been struggling with alternatives for a long time: rendering data is different from receiving data.
We use ViewModels to render data, but it quickly turned out that when it came to receiving data through forms posting and similar, we couldn't really make our ViewModels fit the concept of ModelBinding. The main reason is that the round-trip to the browser often involves loss of data.
As an example, even though we use ViewModels, they are based on data from real Domain Objects, but they may not expose all data from a Domain Object. This means that we may not be able to immediately reconstruct an underlying Domain Object from the data posted by the browser.
Instead, we need to use mappers and repositories to retrieve full Domain Objects from the posted data.
Before we realized this, we struggled much with trying to implement custom ModelBinders that could reconstruct a full Domain Object or ViewModel from the posted data, but now we have separate PostModels that model how we receive data.
We use abstract mappers and services to map a PostModel to a Domain Object - and then perhaps back to a ViewModel, if necessary.
While it may not make sense to group unrelated Entities (or rather their Repositories) into a Domain Object or Service, it may make a lot of sense to group them in the Presentation layer.
Just as we build custom ViewModels that represents Domain data in a way particularly suited to a specific application, we also use custom Presentation layer services that combine things as needed. These services are a lot more ad-hoc because they only exist to support a given view.
Often, we will hide this service behind an interface so that the concrete implementation is free to use whichever unrelated injected Domain objects it needs to compose the desired result.