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

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.

Related

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.

Partial loading of Entity Framework entities and passing them to presentation layer

If I want to select only few columns when retrieving data for an EF entity and cast them to the Entity type, I am not able to do that because it throws an error as mentioned in this post
The entity cannot be constructed in a LINQ to Entities query. I don't want to select all the columns, because I need only few of them. I can use anonymous types, but if I am using repository pattern and want to encapsulate all data access code in repository object and pass strongly typed object collection to the controller (not an anonymous object collection), how can I achieve that? Is the only option to define a DTO object for every subset of the properties for the EF entity? I know there is a risk of losing data with partial loaded entities, but if I am ready to take the risk and want full control over data updates, is that not possible?
for example I would like the "ProductRepository" method signature to be like this
public IEnumerable<Product> GetProducts(int categoryID) //selection of subset of data
and I want to pass this product collection from the controller to the view (in ASP.NET MVC project) and in the view I want to have strongly typed model (with intellisense) object. Is this possible? if not, I may have to reconsider using EF for my project due to this limitation. I am using EF 4.1 version.
Yes the option in this case is special object for each subset of properties you want to select. You can call the object DTO because it is just a result of the projection. This is the correct approach because if your UI doesn't need other properties of entity type it is correct to pass it only specialized ViewModel.
Another more complex (and worse) option is selecting anonymous type inside your Linq-to-entities query, calling ToList and after that construction the real entity type. Partial entity selection is not allowed and projecting to mapped entity types is not allowed as well. That is the reason why you have to use such a cumbersome approach. Example:
// Select anonymous projection
var query = from x in context.Entities
where ...
select new { ... };
// Repopulate entity type
var reultSet = query.ToList().Select(x => new Entity { ... });
Yes, what you want is totally possible using viewmodels instead of entities. Here is example controller code:
var productEntities = productRepos.GetProducts(6);
var productViewModels = Automapper.Mapper
.Map<IEnumerable<ProductViewModel>>(productEntities);
return View(productViewModels);
Your view model will have only the properties it needs for the view. Check out automapper.

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 :)

MVC3 (Models) ...what is the right way to display complex data on the view?

I’m having a philosophical problem with understanding how to use Models on MVC3.
I believe the problem lies from the fact that I come from WebForms :--)
Let's say I have 10 tables on my DB and as expected when I get them into my EF4, I get those Entity classes that represent the tables (and all their FK integer values).
When I want to display data on the View, I cannot display a select * from table because those FK integers means nothing to my users …and also because some data lies on related tables.
So my understanding is that I can create a Stored Proc, create a Complex Type that represent the actual data to display, coming from separate tables via different SQL joins.
QUESTION 1:
On the view, id MVC compliant to use as #model ..that Complex Type?
or shall I always use Models that are created on the Models folder? And if so, does that mean that I have to replicate the Complex Type on a new model inside the Models folder?
Question 2:
Is this the right way …to create specific SP to collect data that will be displayed or ..is it better to use linq and lambda to be applied to the EF4 Types that come from importing the DB into the EMDX designer.
Thoughts ??
FP
The correct way is to always define view models. View models are classes which are specifically tailored to the needs of a given view and would be defined in the MVC application tier. Those classes would contain only the properties that would be needed to be displayed by the view. Then you need to map between your domain models (EF autogenerated classes?) and the view models.
So a controller action would query a repository in order to fetch a domain model, map it to a view model and pass this view model to the view. Top facilitate this mapping you could use AutoMapper. A view shouldn't be tied to a domain model and always work with a view model. This works also the other way around: a controller action receives a view model from the view as action argument, maps it to a domain model and passes this domain model to the repository in order to perform some action with it (CRUD).
So a view model could be a class that is mapped from multiple domain models or multiple view models could be mapped to a single domain model. It all depends on how your domain looks like and how do you want to represent the information to the user.
As far as validation is concerned, I distinguish two types: UI validation and business validation. As an example of UI validation is: a field is required, or a field must be entered in a given format. A business validation is : the username is already taken or insufficient funds to perform wire transfer. UI validation should be done on the view models and business validation on the domain models.
I'm not sure why you need to use a stored proc, LINQ to Entities is able to generate complex types without needing to create stored procs (in most cases). You select subsets of data, just like you would with regular SQL.
As Darin says, the use of a View Model is appropriate for situations where you have a lot of complex data that isn't represented by a single entity. This View Model would contain multiple entities, or even multiple collections of entities. It all depends on how your data needs to be consumed.

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.

Resources