MVC3 - Should I design my Model to be tightly coupled to my View? - asp.net-mvc-3

In working with MVC I am finding my Views to be rigid in terms of their associated Model definition. Should I design my Models around the needs of my view? I realize I can create a container specifically for my view. Then design a second Model in terms of Entities. But, it appears that I always need this stand-between. I mean, there's even a #model to declare what the View is supposed to be coupled to.
For example, I have a View with two tables. The tables both work off the same Entity, so it doesn't make sense to use that Entity as the Model. Rather, the Model needs to be a wrapper that contains 2 of said entities. Moreover, the entities really need to be converted to string[] in order to avoid data massaging in the View.
Am I just too much of an MVC nublet, or is this how MVC is designed to work? Tight relationship with View-Model.

Use a ViewModel for your views. It's bad practice to associate your View with the Model that comes directly from EF.
public class ProductViewModel
{
public ProductViewModel(List<Product> products, List<Category> categories)
{
this.Products = products;
this.Categories = categories;
}
public List<Product> Products { get; private set; }
public List<Category> Categories { get; private set; }
}
ViewModel Best Practices
ASP.NET MVC View Model Patterns

Typically, and I think a lot of the SO/MVC community would agree that following a View Model-esque pattern is extremely beneficial even in the case you're describing. Wrap your entities in a view model class and bind it in the #model statement at the beginning of the view.
The Microsoft guys have recommended the same, though it's not absolute law.
It seems extremely tedious at times, but unless you're writing your own view engines combined with some super advanced model binding logic, the easier path is typically found to be view models. Add more tediousness with data annotations for validation, etc. But to be honest, if advanced model binding and custom view engines are required, your problem has probably been given too much thought.
I agree, don't pass entity classes straight to models. Use your view models to call service or BL classes which assemble the data entities from the data store. I've found the most flexibility when using 1 view per view model, period. To reiterate, that is a 1:1 ratio between view model classes and views. Even if the views have to be broken down into manageable pieces, use display and editor templates to accomplish what you need. It'll help you out later :)

Related

ViewModel vs. Partial Views on Summary/Front Page

I have a design/best practice question relating to MVC3. I have a "front page" for the site that may contain a some summary information for non-related tables from my Model.
Is it better to create Partial Views dedicated to each Model, or to create a ViewModel to bind everything together?
The "pro" of Partial Views is that it truly separates concerns, with the "con" being that the partial views will probably not be reused elsewhere on the site.
The "pro" of ViewModels is that it allows a single strongly-typed object to be applied to a View, with the "con" being that the data is really unrelated and the binding artificial.
For clarity and maintainability I'd choose this
public class SummaryModel
{
public Patial1Model Partial1 {get;set;}
public Patial2Model Partial2 {get;set;}
//etc
}
The main benefit is not reusability (but who knows?) but maintanability. With this model is very easy to modify data for a partial or to reuse it in other places.
summary information for non-related tables from my Model.
In a view, the ViewModel is the Model, In fact the app should not care about tables and other persistence details. The model of the app is the mainly the domain model, the pocos for EF or NH are persistence model. The views know about their model which is different from the app or the persistence model.

ASP.NET MVC3 , Why we need strongly-typed View?

I have read Scott Guthrie's Blog - ASP.NET MVC 3: New #model keyword in Razor
One things i don't realizes is a page will binding value in different ways,but why we have to enforce the view binding from Model?
For example, a user control panel of forum website, it may have the user information, the post history, the user setting etc.
From the view of data model, the binding source can be come from different table : users, posts, user_settings etc.
However, one view only can reference one #model directive.
Actually ,i can add what properties to model that i have to use.
So what is the advantage of make the view became strongly-typed?
However, one view only can reference one #model directive.
Yes, and this should be your view model. A view model is a class that you specifically design to meet the requirements of a given view. And you do this for each view
From the view of data model, the binding source can be come from
different table : users, posts, user_settings etc.
Great, then design a view model that will contain all the necessary properties and have the controller build this view model aggregating the information from the different places and pass it to the view for displaying.
You should never pass your domain models to your views. Because views are normally the projection of one or more domain models => thus the need to define a view model.
1) You can use automatic scaffolding
2) IntelliSense support
3) Compile time type checking
Your view model should be decoupled from your business models.
A single page will have a single view model.
For example:
public class UserPost
{
public string UserName { get; set; }
public string Subject { get; set; }
public IEnumerable<Message> Messages { get; set; }
}
Your UserName property will be coming from the Users table and the UserName field in it.
Your Subject might be coming from a Subjects table and the Messages from another one.
Your view should be concerned only with presenting already processed information, and not querying data sources.
Therefore it is best practice to create a ViewModel per View. This ViewModel contains all properties needed by the view (users, post, settings etc).
In the controller/model you can instantiate the ViewModel and fill its properties. So don't supply a single table/list of records to a view, but a ViewModel.
The advantage is that, with everything strongly typed, there's less chance on runtime errors. Further, when something changes (i.e. database columns), these errors will be detected by the IDE directly.

how can get data from another Table

I am designing a project in asp.net mvc3, i have designed my database in sql server, add i am using ado.net.
This is my controller action
public ViewResult ProductFormulationIndex()
{
return View(db.ProductFormulation.ToList());
}
means i want to display all fields of ProductFormulation table.
this is my table:-
and this is my productCategory Table
in my ProductFormulationIndex.cshtml i want to display Code of ProductCategory Table, not only id. So what should i do in controller or in Model for it ?
you may suggest tutorial related to it.
Thanks in advance.
You need a view model which is specifically designed for the view.
When defining your view models you shouldn't be thinking in terms of tables. SQL tables have absolutely no meaning in a view. Think in terms of what information you need to show and define your view models accordingly.
Therefore, You can define a view model like:
public class ProductInformation
{
...
public string CategoryCode {get; set;}
...
}
Or public Category ProductCategory.
You can use AutoMapper to convert between your real models and the view model you have defined.
You can find a good tutorial at http://weblogs.asp.net/shijuvarghese/archive/2010/02/01/view-model-pattern-and-automapper-in-asp-net-mvc-applications.aspx
Although I may not answer your question you are touching on some interesting points.
I subscribe to the school of thought that says one should not query an object model but rather make use of a denormalized lightweght query layer.
You will pobably quickly run into the lazy-loading and projection issue: i.e. you do not always require the related data and you do not always require all the fields. A query layer takes care of this quite nicely since using a denormalized model means that when you do your query you do not need to do N-number of joins to get the related data. You will still at some point need to gather up the data but you actual view queries will be order fo magnitude faster.
Also, getting all the data (by joining) for your denormalized model is a once-off affair as opposed to doing it each and every time you display the relevant data on the front-end.
Hope that makes sense :)

Why Two Classes, View Model and Domain Model?

I know it could be bad to use domain models as view models. If my domain model has a property named IsAdmin and I have a Create controller action to create users, someone could alter my form and get it to POST a IsAdmin=true form value, even if I did not expose such a text field in my view. If I'm using model binding then when I committed my domain model, that person would now be an admin. So the solution becomes exposing just the properties I need in the view model and using a tool like AutoMapper to map the property values of my returning view model object to that of my domain model object. But I read that the bind attribute on a class can be used to instruct the Model Binder which properties it should and shouldn't bind. So what really is the reason for making two separate classes (domain model and view model) that essential represent the same thing and then incure overhead in mapping them? Is it more a code organization issue and if so, how am I benefiting?
EDIT
One of the most important reasons I've come across for a View Model that's separate from the Domain Model is the need to implement the MVVM pattern (based on Martin Fowler's PM pattern) for managing complex UIs.
I have found that while my domain model gets me 85% of the way to having the fields I want, it has never covered 100% of the values I want on my view. Especially when it comes to permissions and whether or not a user should have access to certain portions of the view.
The design concept I attempt to follow is to have as little logic in my views as possible. This means I have fields in my view model like "CanViewThisField" or "CanEditThisField." When I first started with MVC I would have my domain model be my view model and I was always running into the scenario where I needed just one or two more fields to make my view less cluttered. I've since gone the View Model/Model Builder route and it has worked wonderfully for me. I don't battle my code any longer but am able to enhance my view model as I need to without affecting the domain model.
Another good reason to have a ViewModel is paging large sets of data. You could pass the view an array of Person ( Person[] ) but metadata such as the number of pages, the number of the current page, the size of the page would not belong on the Person class.
Therefore a PersonListViewModel would solve this issue.
A ViewModel holds only those members which are required by the View. They can usually be thought of as a simplification or a "flattening" of the underlying domain model.
Think of them like this:
ViewModel: this is the data that is appropriate to render on this
view
Domain model: this is all the information my application needs
about this entity in order to perform all it's functionality
For example, my Order class has a member called Customer which is a composition association, that is, my Order has a Customer. This Customer object has members such as Firstname, Lastname, etc... But how would I show this on a "details" view of the order or a list of Orders and the Customers who placed them?
Well, using a ViewModel I can have an OrderListItemViewModel which has a CustomerName member and I can map the combination of Firstname and Lastname from the Customer object to this. This can be done manually, or much preferably using Automapper or similar.
Using this approach, you can have multiple Order ViewModels that are specific to different views, e.g. the Order list view might render the customer name in a different way to the Order details view.
Another advantage of ViewModels is that you can cut down on extraneous data not required of the underlying domain object on a view, e.g. if I'm viewing a list of orders, do I really want to see all the customer's contact information, billing details, etc...? I guess that depends on the purpose of the list but, probably not.
Sometimes you need to display the data in a specific manner (ie, displaying a date in the format mm/dd/yyyy vs. yyyy/mm/dd) and often it is easier to make this property in the view and not in the domain model, where you would (or should) have a mapping to a column in your db.
you need to remember
that your domain model classes are only used internally; that is, they are never sent to the
client. That’s what your service model types (View Model types) are used for—they represent the data that will be going back and forth between the client and your service.

How to get data to my view that comes from more than one object?

So I have read some of the similar asked questions, but I don't know if the right questions were asked. It appears there are different ways to get data from multiple entities passed into your View Model, but I want to go about it the correct way.
I basically have 2 entities available in my controller, and I need to pass different information from both entities to my view. I have read about creating a SomeNameViewModel class that would be instantiated in my controller ViewResult method. With the SomeNameViewModel object assigning the data into a single object to pass to the View Model
Example:
public ViewResult List()
{
var vm = new SomeNameViewModel {
products = _prodRepo.All();
catName = <Some Expression>;
return View(vm);
}
But is this the best practice way to go about this?
I am using Nhibernate: So would this be better handled in my Fluent Mapping so that I have access to the other entity through the one-to-one mapping?
Using a model per view is a common (and good) way to go about providing data to your views. View models can encompass values from more than one entity type and may contain ancillary data as well. You might want to also consider using view-specific models for any entities contained in your view model to further isolate your view from your domain objects. This way you can provide to your view exactly the data they need and no more and, if your domain model changes, you may be able to only modify how the view-specific model gets updated from the domain model rather than propagating the change throughout your views.

Resources