How should I be binding my business models to my views? - c#

I've come across an interesting question during my development. Right now, I use a database-agnostic unit of work layer to abstract the access of data from the actual database dependencies in my ASP MVC 4 web application.
Each individual database project which implements the unit of work interfaces are aware of my business models (models that go directly to/from the database). I'm not too sure how I feel about this approach, but that's not the question I am going to ask.
Should I be using a solution like AutoMapper to convert my business models to/from domain models - models that are passed to the view and used for any work that shouldn't have access to database fields (i.e., IDs)?
For example, consider inside my BusinessModels project, I have the following classes
BusinessModels
/UserAccounts/
User.cs
- ID
- Username
- HashedPassword
- Salt
UserSettings.cs
- IsSubscribedToNewsletter
- AllowDirectEmails
Would it make any sense to bind these User, and UserSettings models into a single model using AutoMapper like so
MyProject
/DomainModels/
User.cs
- Username
- HashedPassword
- Salt
- IsSubscribedToNewsletter
- AllowDirectEmails
for the purpose of views?
This question also extends to non-MVC projects but I feel seeing as I am working on an MVC project it would make more sense to ask it in that tag.
TLDR is there any point in mapping business models/entities to view models or does that provide an unnecessary layer of abstraction? And if so, would the Repositories contain business models, or view models (which map automatically to business models under-the-hood)?

You can use view models for two different things:
rendering a new view (GET action), passing the view model object as the model for the view
receiving data back from the view, in a Post Action (POST action), using the view model as parameter
(I know, the second is arguable. But it's not strange to use the view models for this)
The model for the GET action needs all the properties neccessary to render the View:
the values of the entity you're showing/editing
extra values needed to render the view (for example SelectLists for drop down lists)
Suppose that you have a User which can belong to one UserGroup.
In this case, if you want to edit the user, the model needs:
the User data
a list of UserGroups
I'd use a model like this:
public class EditUserModel
{
public User User {get;set;}
public SelectList UserGroups {get;set;}
}
As you can see, I directly add the User as a property. But I don't add the list of categories as a property, because I don't need the whole list of categories, with all their properties in the view. Besides, if you unit test the controller you can verify that the SelectList is as expected (that couldn't be done if you created the User Groups list in the view)
But, what if you don't need all the properties of the user in the View? Is it worth removing the User property, and add individual properties for Name, Email, JoinedData, Active... ? I think the anser is NO. Imagine you add/remove or rename some of the User entity properties. If you had individual properties in the view model, you'd have to change them as well, before updating the View. And, if you rely on automatic mapping (auto mapper, value injecter) you would't even realized if you make some mistake.
I also said that the view model can be used for posting back data to the controller. So you could do this:
[HttpPost]
public ActionResult Edit(EditUserModel userModel)
If you do so, the model binder will populate the userModel with the values in the form controls. So you'lll get back a half empty model. In this case, the UserGroups list would be null, and, depending on how many of the User's properties you edit, the User could also have many null/non-initialized properties.
To avoid making errors, in some occasions is advisable to create a different model (and probably auxiliary classes) to make it clear what is expected to be posted to the model.
For example, if you have an action to show the whole user data, but which only allows to change its password, you could create a class with two properties: Password, and PasswordConfirmation.
In this case, the view model for the POST could only have the Password and PasswordConfirmation. And derive a model for the GET which has this inherited properties, and also the list of User Groups and the User.
Why inheriting and not using independent classes? Simply beacuse when you use something like Html.TextBoxFor(m => m.User.Name), the Model Binder will be able to set the Name property of the User property, only if the parameter for the post action has the same structure. I.e. if the view model for the get has this structure:
public ChangePasswordModel
{
public string Password {get;set;}
public string PasswordConfirmation {get;set;}
// extra properties, like the list of user groups, the user data...
}
And the model for the post has this structure:
public PostedChanegPasswordModel
{
public User User {get;set;}
}
The content of the input rendered by Html.TextBoxFor(m => m.EditedUser.Name) won't be bound to the User.Name of the PostedEditViewModel.
But if you make this:
public EditUserModel : PostedEditUserModel
{
// extra properties, like the list of user groups
}
the data will be bound without any problem.
In general you have to be careful with the models you use for posting and getting. And I recommend using as many different view models as neccesary.
When to use automatic property mapping to completely new view and different models?
You must have a very strong reason to have different view models. This could be a result of starting the application from outside in (i.e. design first) or because a team is developing the UI before or while the business logie is being implemented.
In this case you can find that the classes for the view models, and the views themselves are already defined, and are quite similart to your entities, but not exactly equal. This is one case when I think it can be good to use mappers.
The other reason to use different classes would be to decouple the interface from the logic. But this usually only happens in the previous case.

Regards viewmodels I treat them like a summary of the data you wish to work with.
So taking from your example, your viewmodel would contain data from both the User and UserSettings classes. Let's say you had a view named UserData.cshtml then I would code it up like so:
public class UserDataViewModel
{
public string Username { get; set; }
public bool AllowDirectEmails { get; set; }
// etc ...
}
public ActionResult UserData()
{
var viewModel = new UserDataViewModel();
viewModel.UserName = "Whatever";
viewModel.AllowDirectEmails = false;
// Or however you get the data for the user.....
return View(viewModel)
}
Hopefully you get the idea. So you are on the right track with merging information from externals classes into one viewmodel class. Bascially tie everything together in the viewmodel class.
I name the viewmodel class the same as the view that it's going to be used for. This can help documentation, as well as make it easier for devs new to the code to follow.

Related

WPF - MVVM Viewmodel setup

I'm having some issues with the setup i'm currently using with my mvvm application. Having seen some posts on here, i get the feeling i may be doing this slightly wrong.
I have several models which contain lists of child models such as:
Project - Contains a list of proformas
Proforma - Contains a list of shipments orderedItems
Shipment - Contains a list of Containers
Container - Contains a list of packages
We do not have any viewmodels that relate directly to these model currently, we instead simply have viewmodels that represent the list of models, for example we have a proformalistviewmodel which simply contains a list of proformas.
My issue is, that with this setup i'm a little confused as to what viewmodel should own which data, for example the ProfomalistViewModel has a reference to the currently selected Project, all the data management for these models (the loading and saving of the list of proformas) is done via manager classes which are loaded via DI.
My question is should i instead be following what I'm seeing and having a ProjectViewModel which contains a list of proformas, and a ProformaViewModel which contains a list of shipments and ordereditems and so on.
The reason for this, is that originally none of the models we're linked, projects did not own a list of proformas they were instead loaded separately via the managers using the selected project ID (using a relational db) and we're currently changing the models to the system i described above.
A viewmodel should be a model of the user interaction for a particular area of functionality
For instance, if you have a project list page and the user can do certain things like delete a project, edit a project, print information about the project then you should design a viewmodel that contains the data and actions associated with this interface:
e.g. the viewmodel should contain:
* A bindable container for the project data (list of projects)
* Actions that handle edit/delete interaction
* An action to handle the print functionality
The actual functionality inside these actions may not be contained within the viewmodel (the VM may have received injected services such as the print service or the project repository) but the responsibility of execution of these actions lies with the VM.
It may also be necessary to wrap each data item (project) in a viewmodel so that additional interaction dependent properties/actions can be added - such as the 'selected' property (imagine the user wants to multi-select a load of projects in the view - you could add a selected property to the ProjectViewModel which will wrap each project which makes binding easy)
You may end up with something like the following:
public class ProjectOverviewViewModel
{
public IList<ProjectViewModel> Projects { get;set; }
public ProjectViewModel SelectedProject { get;set;}
public void EditSelected()
{
// Code to open edit page for the selected project
}
public void Print()
{
}
}
and the ProjectViewModel with a selectable property
public class ProjectViewModel
{
// Either put the actual data item in here and wrap it:
public Project Project {get;set;}
// Or copy properties onto the viewmodel using automapper or some other mapping framework...
// or manually :(
// e.g. properties mirrored from the entity object:
public int ProjectId { get;set;}
public string ProjectName { get;set;}
// The selected property - now your 'Selected' logic is a function of the view/viewmodel
// not the entity. The entity should only be concerned with data persistence
public bool IsSelected {get;set;}
}
You may also want to composite viewmodels together in order to build more complex views. Imagine you have a projects page and a "users involved in a project" page, and you wanted another page that showed both side by side (and allowed you to click a project which would refresh the users pane) - this is possible by compositing the viewmodels (by creating another viewmodel which contains the two viewmodels as properties and wires up the interaction between the two)
public class ProjectAndUserOverView
{
public ProjectOverviewViewModel ProjectOverview {get;set;}
public ProjectUsersViewModel ProjectUsers {get;set;}
// Code here to listen for property changes in ProjectOverview and if SelectedProject changes
// call ProjectUsersViewModel to refresh the data for the selected user
}
Ultimately you are just modelling the user interaction, and the more modular you can make it, the easier it will be to make cleaner more maintainable code
There are some good MVVM frameworks - my personal fave is Caliburn Micro as it makes the above very easy (it heavily uses conventions by default) and is easy to get into.
MVVM is design pattern which have 3 parts: Model, ViewModel, View. DIagram looks like this:
http://en.wikipedia.org/wiki/Model_View_ViewModel#Pattern_description
You use ViewModels wrong. Only data for displaying should be in ViewModel.
Your Model for example:
public class Project
{
public Proforma Pr{get;set;}
}
public class Proforma
{
public string Name{get; set;};
}
You have View for project display(I inject ViewModel to constructor, tou can use DataContext instead):
public partial class ProjectView
{
private ProjectViewModel vm;
public ProjectView(ProjectViewModel vm)
{
this.vm = vm;
}
}
If you want to display proforma name on Project view, you should provide it as string in ViewModel.
public class ProjectViewModel
{
private Project pr;
public string ProformaName{get{return pr.Pr.Name;}}
}
If you provide Proforma like proforma, your View will know about model. It will be a violation of the pattern.
My five cent is that MVVM is a pattern, not a religion. I use it at far as it goes and makes sense. There's many parts where MVVM is undefined (like user interaction from commands), and I read a lot about ViewModels being created just to fit MVVM (which bloats both design and object count). I would suggest you think more DataContext-wise, like "Selections of global interest are kept in a global DataContext, Proforma related data is kept in a Proforma DataContext" and so forth, where DataContext is some sort of ViewModel. In the end, you'll probably wind up rigging those up with UI.
You shouldn't create ViewModels for your model objects.
Generally speaking, a ViewModel should belong to a UserControl. Its role is to wire your view (your XAML) together with your model (business logic).
In your case, if I understand it correctly, you have a bunch of classes that implement business logic (Project, Shipment etc.). Your ViewModel will have access to the business logic, and provide properties for your view to bind to.
I do not see any problem with having view models that wrap model data objects. Viewmodels do not have to be "one per view". They can represent a row in a list or whatever.
Having said that, I am quite happy binding directly to model objects and I do it a lot. The only time I create a view model to wrap it is if I need extra state per object that is required by the view.

Complex domain model based on companies and not users

I have a few different types of companies that can access my web application e.g
Different types of Companies:
Client
Supplier
Agent
Each have their own table in the database, linked to the main table Company which stores all common data e.g. Address, Tel, Email, TypeOfCompany with a FK to the relevant table (Client etc.)...
What is the best way to handle this OO throughout my app?
I currently do something like:
public class CompanyDTO
{
public int Id {get;set;}
public string Name {get;set;}
public Address Address {get;set;}
public string Type {get;set;} //type of company
//etc...
}
then inherit from that class and add aditional properties e.g.
public class ClientDTO : CompanyDTO
{
public string Key {get;set;}
public Address Billing {get;set;}
}
However I am finding it problematic at times for example
Supplier user wants to access: AllCompanies, - show a list of all companies
Then the user from the Supplier Company wants to view a specific companies detail, now if it is a client I will need to show ClientDTO or SupplierDTO? In this instance I want to show that specific companies Full details
What would be the best way to handle this?
e.g. GetCompanyByID(int companyid); or GetClientByID(int clientid); What type of object should I return in both instances, presuming I want Client details in both instances...
Funny how databases don't understand OO practices like derivation, aggregation, and encapsulation. It is an unfortunate failing but still only a part of what is overall referred to as "database impedance mismatch".
What your attempting to do is common enough there are several solutions...
Firstly there is the choice of the data model stored. There are basically three possibilities.
Split the tables as you have done.
Declare all fields for all derived types in the same table.
Use a blob field (json/xml/whatever) to house the uncommon fields.
Secondly there is the issue you bring up, requesting the data from the database. Primarily this is centered around the request of a list of the 'common' base type and how to then access the uncommon fields that they don't share. Again there are several possibilities.
When listing the base type only those common fields are returned. Then subsequent queries are issued one-off to lazy load the other fields.
When listing the base type all other tables needed are also outer joined to the main table to ensure all fields are available to instantiate the object model fully.
When listing the base type, multiple result sets are returned, one for each 'sub type' table that may be needed for the results. The client then pieces the records together building up the object model until it is complete.
Not an exhaustive list, but a start. Personally I prefer to avoid data models like the one you describe for this reason. Essentially my preference is to have the data model define the union of all fields (model #2), and then use a business layer to determine what properties are exposed, validated, required, etc. I have also used model #3 above, using blob fields for multiple values, and it works well enough also depending upon need. The only downside to model #3 over #2 is that you will not be able to query or sort on those fields. Ultimately either approach still needs the business logic layer involved to know what data to expose.
Remember databases are stupid, treat them as such and you will get along well. (note: this advice does not work on people, just databases)
I want to access: AllCompanies, - show a list of all companies
When you want a list of companies, aren't you asking for the general details that instances of CompanyDTO describe? Maybe your data access (service, repository, etc) could look like:
public class CompanyRepository : ICompanyRepository
{
public IEnumerable<CompanyDTO> GetCompanies()
{
// get companies and map them to CompanyDTO objects as necessary
}
}
Then you asked (well, there is a question mark)
Then I want to view a specific companies detail, now if it is a client I will need to show ClientDTO or SupplierDTO?
I'm assuming this would be a separate view, or at least broken down into a separate partial views. But, you could use Display Templates to describe your child types of companies since you've describes an inheritance above.
I will pretend you showed us your controller and it looks like this:
public class CompanyController : Controller
{
public ActionResult Details(int id)
{
CompanyRepository repo = new CompanyRepository();
return View(repo.GetCompanyById(id));
}
}
Then, add a strongly-typed view named Details, that inherits a CompanyDTO object, and add a call to Html.DisplayForModel():
<%--some scaffolded code ommitted for brevity--%>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<%= Html.DisplayForModel() %>
</asp:Content>
Then, here's where display templates come in. Add a folder:
~/Views/Company/DisplayTemplates
Then add to that folder 3 strongly-typed, partial views--one for each child type. Visual Studio will help you with this:
Right-click the DisplayTemplates folder --> Add View...
Name it "ClientDTO" (this is important)
tick "Create a partial view"
tick "Create a strongly-typed view"
Select the ClientDTO class
Select Details for view content (this will give you some auto generated markup)
Click Add
Repeat this process for other child types and the correct template will be rendered based on the child type of the model passed to your Details view.

Confused with Model vs ViewModel

I am Learning ASP.NET MVC and downloaded a couple of sample apps. MusicStore etc...
I am coming from a wpf background where we had the MVVM Pattern.
I have noticed that they used the concept of model and ViewModel.
In MVVM is pretty clear that you bind the view to the ViewModel injecting the model into the viewModel.
In MVC you have a controller but I am not sure and confused how the all ties together,as I cannot see the model injected into the ViewModel
I have the following structure
MyCompany.Entities.dll (All the models go here) EG Product
MyCompany.Dal.dll (All the repositories go here)
MyCompany.Services.dll (called by MyCompany.WebUI.Controller calls MyCompany.Dal)
MyCompany.WebUI.MyApp
MyCompany.Tests
From some of the examples I have seen your Model acts as a ViewModel.Am I correct?
Let's take a controller i have something like
public class ProductController
{
public ProductController(IProductRepository productRepository)
{
//omitted as not relevant
}
}
public class ProductVM
{
public ProductVM()
{
// Shouldn't we inject the model here RG Product
}
}
Is there some N-tier examples out there I can refer to?
Is the concept of ViewModel a valid one in MVC?
What is the standard?
Thanks for any suggestions.
Use ViewModels to simplify the View.
For instance, you might have a deep object graph with Products, Order, Customers, etc - and some information from each of these objects are required on a particular View.
A ViewModel provides a way to aggregate the information required for a View into a single object.
ViewModels also allow for things like data annotations and validation - which does not belong on your model, as your model should stay "domain-specific".
But in reality, ViewModels are nothing more than a simple wrapper for your domain objects.
Use a tool like AutoMapper to map back and forth between your ViewModels and domain models with ease.
Personally I always bind to ViewModels in my Views, never to the domain models, even if it's a single object. Why? Well I like to decorate my ViewModels with UIHints, validation, data annotations. Just the same way your domain models are enriched with domain-specific rules and business logic, so should your ViewModels be enriched with UI-specific logic.
If you simply have a object with a 1-1 representation of your domain model, you are missing the point of ViewModels.
Add to the ViewModels only, and nothing more, what is required for a particular View.
Example controller action
public ActionResult CustomerInfo(int customerId)
{
// Fetch the customer from the Repository.
var customer = _repository.FindById(customerId);
// Map domain to ViewModel.
var model = Mapper.Map<Customer,CustomerViewModel>(customer);
// Return strongly-typed view.
return View(model);
}
The difference between MVC and MVVM is that MVC has one set of classes for the data entities. In MVVM you have 2 - one set for binding to your views, and one set for managing the data persistence (which could be in a separate WCF service for example).
The benefits of MVVM are that the model bound to the views is relevant to the UI and completely independant from the persistence Model.
Which to use? Well it depends on how closely the data structure required by your Views maps to the structure of the database. When it is similar - it is possible to bind the DataEntities from your DAL directly to your view - this is the classic MVC pattern. However, you gain much with a separate ViewModel as you can extend these classes with View specific behaviour (e.g. Validation) that your DAL should not be concerned with.
For all but the most simple applications, I would recommend use of a separate ViewModel.
Extremely simple,
ViewModel can be the combination of multiple Model classes, to display or transforming the data to and from within the Network, may be via API calls.
However, Model class is nothing but just be specific to any particular entity, Object or strict to a particular Table.
Ex- For "EmployeeViewModel" can be the combinations of Multiple Model Classes i.e. EmpBasicDetails + EmpAddressDetails +EmpExperienceSummary.
Whereas, "EmpBasicDetails" - is specific Model class which contains the Employee Details specifically.
~Cheers,

Drive an Aggreagte View Model by setting properties or calling methods?

I'm debating with myself about the best practice approach to controlling an Aggreate View Model class that I've created for my app... Let's say I have an aggregate model that has a PurchaseOrder object and a list of line items that belong to that Purchase Order, and a few other auxuliary/related objects. This view model is just a wrapper around all these objects that you would typcially need when working on any give PurchaseOrder.
After after creating an instance of this view model, I then want it to load up a PurchaseOrder (and it will load the PurchaseOrderLineItems automatically and saturate all the other related objects)...
So, to instruct the view model to load up a PurchaseOrder, is it more acceptable to:
Instruct the view model by setting a property on it (and let the property setter of the view model class respond by loading up the data)
ViewModel.PoNo = 1234;
or
Call a method on the view model to do the work:
ViewModel.LoadPurchaseOrder(1234);
Just to give a few mode detials about the Aggregate View Model, it basically looks like this:
public class ViewModel
{
//-- private fields
PurchaseOrder _Po = new PurcaseOrder();
List<PurchaseOrderItem> _PoLineItems;
Vendor _Vend = new Vendor();
int _PoNo;
//-- public properties here
ViewModel(){} // Constructor
}
Does this ViewModel serve any purpose other than relating all the PurchaseOrder informaton together? If not i would say you should pass your purchase order in the constructor of ViewModel because it seems like ViewModel would only be in a valid state if it had a PurchaseOrder.
EDIT: Given the 2 options you have listed, I think a method call makes more sense than setting a property as it is easier to tell that you are loading a PurchaseOrder into this ViewModel. As a developer, I wouldn't think that setting an integer property would end up loading all kinds of objects on the ViewModel, but one might expect that from calling a method.

MVVM where to put Data Access Layer?

I am investigating WPF's MVVM design pattern. But am unsure where to put the Data Acess code?
In some examples I have looked at, data access is performed directly in the ViewModel. It seems odd to put something like linq to sql in the ViewModel? Other examples have a seperate project for Data Access, this seems more like it?
Is this there a general approach? I feel like I am missing something here!
Thanks
Here's how I've been organizing my MVVM w/ LINQ projects:
Model - I think of the Model as the state of the system. It provides an interface to the data, and it keeps track of system status. The Model does not know about the ViewModel or View--it just provides a public interface to its data and various events to let the consumers (usually ViewModels) know when the state has changed.
ViewModel - The ViewModel is in charge of organizing or structuring all the data needed by the View, keeping track of the status of the view (such as the currently selected row of a data grid), and responding to actions on the view (such as button pushes). It knows what the view needs, but it doesn't actually know about the view.
View - The View is the actual look and feel of the UI. It contains all the built-in and custom controls, how they arranged, and how they are styled. It knows about the ViewModel, but only for the purpose of binding to its properties.
Gateway - This is the part that directly addresses your question. The Gateway (which is basically my way of saying "DataAccessLayer") is its own separate layer. It contains all the code (including LINQ queries) to CRUD or select, insert, update, and delete data from/to your data source (database, XML file, etc.). It also provides a public interface to the Model, allowing the Model to focus on maintaining system state without having to concern itself with the details (i.e., the queries) needed to update the data source.
DataAccess Classes - In C#, these are very simple classes that model your elemental data objects. When you select something using a LINQ query, you will usually create an IEnumerable<T> or List<T> where T is one of your data objects. An example of a data object would be:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
The big advantage of a design like this is that it really separates your concerns. Everything has a specialized job, and it's (usually) pretty easy to know what kind of thing goes where.
The disadvantage is that it may be overkill for small projects. You end up creating a lot of infrastructure for public interfaces that basically pass a single wish through several layers. So, you might end up with a scenario like this: [user clicks Submit, ViewModel tells Model to AddNewPerson, Model tells Gateway to InsertPerson] instead of a scenario like this [user clicks Submit, ViewModel adds new record to the database directly].
Hope that helps.
I would add another layer, essentially what you want is a data factory. You want to create a set of classes that will CRUD to the database for you and return clean POCO objects to the ViewModel.
A good example to look at would the Nerd Dinner book. It covers MVC not MVVM but the patterns are very similar and the way they access data in that solution would be good starting point.
Hope this helps.
Data access should not be in the view model, as this is supposed to be a view specific (possibly simplified) representation of the domain model.
Use a mapper of some sort to map your view model (the VM in MVVM) to your model (the first M). New objects in your model can be created using the factory pattern. Once created, you can store them in a database using the repository pattern. The repositories would then represent your data access layer. In your repository you could use an O/R mapper like NHibernate or Entity Framework.
EDIT:
I see that GraemeF suggests putting the data access code in the model. This is a NOT a good approach, as this would force you to update your domain model if you were to move from e.g. SQL Server to Oracle or XML files. The domain objects should not have to worry about how they are persisted. The repository pattern isolates the domain from its persistence.
MVVM stands for Model, View, and ViewModel. The piece you are missing is the Model, which is where your data access code lives.
The ViewModel takes the Model and presents it to the View for display, so typically you would have something like this:
class PersonModel : IPerson
{
// data access stuff goes in here
public string Name { get; set; }
}
class PersonViewModel
{
IPerson _person;
public PersonViewModel(IPerson person)
{
_person = person;
}
public Name
{
get { return _person.Name; }
set { _person.Name = value; }
}
}
The PersonView would then bind to the properties of the PersonViewModel rather than directly to the model itself. In many cases you might already have a data access layer that knows nothing about MVVM (and nor should it) but you can still build ViewModels to present it to the view.
Your ViewModel should be a thin layer that just services the view. My rule of thumb: if it has to do with the presentation of the UI, then it belongs in the ViewModel, otherwise it should be in the Model.
The WPF Application Framework (WAF) contains a sample application that shows how the Model-View-ViewModel (MVVM) pattern might be used in combination with the Entity Framework.

Categories

Resources