Should i consider ASP.NET MVC ViewModels only containing flat and primitypes types or it should contains complex Core/Domain model types ?
I'm looking for best practices.
Thanks.
Do what makes sense.
There are no authoritative sources that will tell you that using ViewModel with primitive types is going to kill kittens, because they would be wrong. And for every expert out there who tells you that using ViewData with magic strings is perfectly OK, there will be purists out there who will tell you that strongly-typed objects are the only way to go.
I write applications that read from a database and display data in a web page. I have tried it both ways (using ViewData and using a ViewModel object), and I am happiest when I have a ViewModel object to project into the web page. The ViewModel class is a place to encapsulate things like validation and view logic, if I need them, and it provides the data structure and strong typing that I like.
If I just want to display a record from one of my Linq to SQL classes, and I don't need extras such as dropdown data lists, I might use the Linq to SQL object directly. But if I do have extras, I put everything into a ViewModel class, and project that ViewModel instance (or an IEnumerable or IQueryable of them) into the view.
So I seldom use ViewData, but that's just my style. It's nice to know that it's still there if I need it.
Related
I realize this doesn't necessarily apply to MVC exclusively, but bear with me.
Working with entity framework and models, I've read several articles on "best practices" where some people claim using repositories and unit of work is better, others claim it's overkill and using your models directly within your controllers with linq is better, so on and so forth...
Then we have view-models and lazy loading methods, but then with linq we can use joins to add multiple "models" to our data retrieval to fetch whatever we need directly in our controller or helper class.
I realize a lot of this ties back to the "separation of concerns" that is MVC and we can create multiple layers to map our data back whichever way we want, which is great, but let's say for argument sake my app run exclusively on MS SQL, with no chance of ever transitioning to another database type, will adding all the additional layers of separation to map data back give me any real benefit? I'm just trying to understand at which point does one conclude it's better to do it this way over that way? I know some of this might consist of personal preference, but I'm looking for REAL LIFE scenarios where it's easy for me to conclude one way it better than the other AND what questions I should ask myself when deciding how many mapping layers do I need to get my data from my database to my view?
One of the real benefits is when your models or your UI need to change independently of each other. If your view is only tied to a ViewModel instead of your entity, then you can make all of the mapping changes in one place (your controller) instead of needing to go through every view that your entity is being used and making changes there. Also, with ViewModels, you have the benefit of combining multiple data sources into a single object. Basically, you get a lot more flexibility in how to implement your UI if you don't tie it directly to database tables.
A colleague of mine doesn't want to bind from the View directly to the Model. For example, in the Model, he has a ObservableCollection and in the View he wants to use it. Instead of directly using it like I would do it (e.g. {Binding Model.Collection} he has another ObservableCollection in the ViewModel which has exactly the same data as the ObservableCollection in the Model. He is synchronizing both ObservableCollections with each other through events.
What are the benefits of his approach? I, personally, disapprove of his approach because it just adds duplicate code and since you have to synchronize the ObservableCollections yourself it's also more error prone. My colleague says he wants to do it this way because then he can change the Model without changing the View.
EDIT:
Some highly upvoted answers [1][2][3] support my in my thinking that it's really okay to bind directly to the Model.
It all comes down to code separation and reusability. Ideally, the View should be completely separated from the Model. If the View doesn’t rely on a specific implementation of the Model, then it can be reused with a different model to present some other data.
So, suppose you have a AlbumView and your current Model is Album, but in future you have decided to also add Movie or Book to you library. you could still use the same AlbumViewo display your movie and book objects. Furthermore, if you want to create a new project that has something to do with albums, you could simply reuse your Album class, because it’s not dependent on any view. That’s the strength of MVVM or MVC.
So for me, I would say, that your colleague is right, because Model naturally reflect the Data Access Layer Entity, where it will be stored and handled. In addition to that, Model may have more properties related to Access data layer such as created indexing. While you ViewModel is only related to the view and the presentation logic of your application. It only reflect what the user is going to see.
I would say using an ObservableCollection in the Model layer is wrong. By adding that you are basically saying "Model object stores data and notifies when it changes".
The role of the ViewModel is to manipulate the Model and provide an interface to the View for presenting the Model.
I believe your colleague is right because he is enforcing separation of concerns such that manipulating the Model should not impact the View.
I am trying to implement the MVP design pattern for the first time, using webforms and SQL Server.
I want to use a Gridview to display data from the database.
However when I set the ControlSource of the Gridview from the Presenter, it makes the Default.aspx View dependent on the Dataset. This seems wrong, because if I swap my SQL database for something else, the view would have to change as the GridView might not work.
Is it bad practice to do this, if so how can it be avoided?
I have added my notes to help illustrate the problem (note the red arrow between DefaultView and Dataset):
I really can't understand why, having such rich model layer, would you ignore it and bind the view directly to a data set. Why on Earth you don't bind to a list of objects exposed in the model?
Grids in ASP.NET do fine if you bind to IEnumerables, a list of object is fine. You could even have a thin adapter, the ObjectDataSource that controls the way a grid retrieves and updates the data to support sorting and paging.
So, answering your question:
Is it bad practice to do this, if so how can it be avoided?
To me, the view peeks too deep under the cover, it actually peeks into internal details of the DAO implementation. You could avoid it by coupling the view to the model members instead of the model internals. And while your model looks OOP (Customer), data set sounds like the internal way the db access is implemented.
BTW. I would consider switching to an ORM like Entity Framework. It makes implementing object models much easier than introducing a layer of data sets.
First of all , I use EF into Dal layer (separeted project from MVC, same solution). The generated models from EF's EDMX file are the actual models from Model layer?? If so, how do I access these models to work in MVC's View layer? I think it's wrong accessing data layer directly from view to work with these models, and If I make a Model layer with "my models" and translate Dal's models into mine models... it'll be duplicated code.
Probably I'm getting something wrong, but most of egs. are with code first approach, and I can't figure out this.
You are right in your idea of not accessing access the Models in your DAL directly from your presentation layer.
To avoid duplicating code when translating your DAL objects into the Models used by your views, you could use something like AutoMapper, which is supposed to do the heavylifting for you in exactly that scenario.
I think it's wrong accessing data layer directly from view to work with these models...
That's right, the appropriate method is using View Model
When you have dozens of distinct values to pass to a view, the same flexibility that allows you to
quickly add a new entry, or rename an existing one, becomes your worst enemy .You are left on your
own to track item names and values; you get no help from Microsoft IntelliSense and compilers .
The only proven way to deal with complexity in software is through appropriate design. So defining an object model for each view helps you track what that view really needs. I suggest you define a
view-model class for each view you add to the application.
-- "Programming Microsoft ASP.NET MVC" by Dino Esposito
A ViewModel provides all information that your view requires to make itself. To transfer data from ViewModel and a business entity you can use AutoMapper.
Don't worry about duplication, those are two different concept and should be separated from each other; it makes your application easy to maintain.
I may be mistaking but to me, using generation from EDMX provides you with the DbContext which could be considered as the DAL and entities which could be considered as the Model.
So you might directly manipulate entity instances as your business object. Manipulation of the base through the DbContext should appear in the BLL layer. Additionally, you might implement DTOs where needed.
This, of course, assumes you want to use entity framework code generation. Other options like using POCOs might be more relevant considering your overall architecture.
I use a view model in my local project and the models in the other project. Then put references to the models im gonna use on the page in my view model. Then reference the view model on my page. Let me know if that sounds like something you want to do and I can edit in some code.
I need to understand the best practices of MVC architecture implementation. I'm a Java and C# programmer. I know the basic of MVC. But i'm sorta confused on how to implement it. I know how to make a simple MVC based calculator. But here's the thing.
I wanted to make a simple database editor application using MVC. Should I construct a model and controller for every rows (objects) of the table? If so, how about the view of every objects? How do i handle them being deleted, updated, and inserted. And should I make the model and controller for the editor which is also a view?
If you don't want to use the Java Persistence API, consider using a Class Literals as Runtime-Type Token in your TableModel.
At first, if you are comfortable with Java try the Spring MVC. There are a lot of tutorial regarding this. If you are much more confident in C# try ASP .NET MVC 3. I will prefer the later one as in this case you have to deal with less configuration.
Now I will answer your question one by one.
At first create a model for every table in your database. Actually these models (which are nothing but classes) when instantiated are nothing but an individual row of the respective table. Your ORM (object relational mapping) tool (For java you can use hibernate, for c#.net you can use entity framework) will provide you specific methods (save(object), add(object), delete(object)) for updating the database
Now each controller should work with a specific model (Here I am ignoring the complexities of using multiple models.). But it may generate numerous views. By clicking a link in your view page you actually invoke the related method in the controller. The controller than binds the Data (if any) with the specific view realted to that link and then the view is rendered. So for deleting a row there should be a method named delete() (you may name it anything you want, so dont be confused) in your controller. When you want to delete a row invoke that method and inside the method remove that row by using something like delete(object) (these methods will be provided by your ORM) and then return another view. The same thing is applied for adding and updating data. But each method may generate different views. Its upto you that which view you return in each of these methods.
I hope the answer helps you. Cheers !!!