ASP. NET MVC: Mapping Entities to View Model - asp.net-mvc

I'm trying to clean up my action methods in an ASP.NET MVC project by making use of view models. Currently, my view models contain entities that might have relationships with other entities. For example, ContactViewModel class might have a Contact, which might have an Address, both of which are separate entities. To query for a list of Contact objects, I might do something like the following.
IList<Contact> contacts;
using (IContactRepository repository = new ContactRepository())
{
contacts = repository.Fetch().ToList();
}
EditContactViewModel vm = new EditContactViewModel(contacts);
return View(vm);
This method brings on a few problems. For example, the repository is queried within a using statement. By the time the view renders, the context has gone out of scope, making it impossible for the view to query the Address associated with the Contact. I could enable eager loading, but I'd rather not. Furthermore, I don't like that the entity model has bled over into my view (I feel like it's a bad idea for my View to have knowledge of the relationship between Contact and Address, but feel free to disagree with me).
I have considered creating a fattened class that contains properties from both the Contact and Address entities. I could then project the Contact and Address entities into my new, flattened object. One of my concerns with this approach is that my action methods may get a little busy and I don't think AutoMapper is able to map two or more objects into a single type.
What technique is/are preferred for overcoming my concerns?

Automapper will work for your case. What you have is an object graph, a thing has some more things, which Automapper handles fine.

Taking these concerns in order...
First, if you are worried about the using statement and the repository (I don't know if it is LINQ-to-SQL or LINQ-to-Entities, but it doesn't matter), what I would recommend you do is implement IDisposable on your Controller, and then store the repository in a field either on the model or in the controller or somewhere where you have access to it in the view (if you need it, if the model has knowledge of it while the object is "alive" then you just need to keep it around for the life of the controller).
Then, when the request is complete, the Dispose method on your controller is called and you can dispose of the repository there.
Personally, I have a method on my base controller class which looks like this:
protected T AddDisposable<T>(T disposable) where T : class, IDisposable
{
// Error checking.
if (disposable == null) throw new ArgumentNullException("disposable");
// Add to list
...
}
Basically, it allows you to store the IDisposable implementations, then in the IDisposable implementation of the controller, it iterates through the list, disposing of everything.
Regarding the exposure of the address on the entity model, I don't see this as a bleed issue, personally. The address is part of the composition of the contact (IMO), so it would be wrong to not have it there.
However, I don't disagree if you don't want it there because you want to focus on one type in one controller at a time, etc, etc.
To that end, you would want to create Data Transfer Objects which basically map between the type you expose in the view model and your entity model.

Related

complex hierarchy updates based on form input

I am trying to understand the best way to work with complex hierarchies of objects that i manipulate based on data on forms in Grails.
I cannot use the command object as my form is dynamic (users can add any number of records). I am told we should parse the params in controller and let services do the transaction activities on the domain objects and thus reduce coupling. Sometimes this doesn't seem straightforward.
I have a few lists of child domain objects in a base domain object that is being 'updated' which means the list could have grown or reduced, meaning some domain tuples will need to be added/removed, how do i pass that information from controller to service without making a function with 8 parameters? If anyone has any strategies you've used, please share. I am sure this is not uncommon but I haven't seen any discussions on such a question.
e.g.
class DomainA {
List<DomainB> bList
List<DomainC> cList
DomainD domD
}
class DomainD {
List<DomainE> elist
}
How about relying on ajax. You might save classD and then class A, or use a command object to save both. Then with the Id´s of these two classes you might add everything else you need using ajax.

Architecture: Avoiding duplicate model/modelview code in MVC/Entity Framework Project

I'm new to the whole ASP world and I'm getting my feet wet by building a C# MVC3/EF4 project. I'm finding it hard to keep from duplicating a bunch of code in my models and view models. Consider an object Foo. I need to do the following things with Foo:
Store records of type Foo in my database.
Allow users to lookup records of an individual Foo (pass instances of Foo to a view).
Allow users to create new instances of Foo (pass instances of Foo to a form).
Let's say I also have a type Bar. A Bar contains a list of Foos. There are two requirements here:
Users can view a list of Bars.
When the user clicks on a specific Bar, it shows all of its Foos.
So, a sketch of my basic objects look like this:
class Foo
{
string FooName;
int Id;
}
class Bar
{
List<Foo> FooList;
int Id;
string Baz;
}
But when I start thinking about the different views, it begins to get messy:
The views shouldn't have any write access to any of the data members.
There's one view that takes a list of Bars but doesn't care about Bar.FooList. Let's say I also want to be good about resource management and close the DbContext as soon as possible (i.e. after the object is in memory but before I render the view). If I just pass it a list of Bars and the designer tries to access the FooList by mistake, we'll get a runtime error. Yuck!
Ok fine, I just create a distinct ViewModel for each view that has read only datamembers, no problem.
But both the database model and the form models will need to have DataAnnotations attached which say which fields are required, max length of the strings, etc. If I create separate form models and database models then I end up having to duplicate all these annotations. Yuck!
So, that's my architectural dilemma: I want to have succinct view models which restrict the views only to reading the data they are supposed to access. I want to avoid repeating data annotations all over the place. And I want to be able to aggressively free my DB resources as soon as possible. What's the best way to achieve my goals?
My advice is do NOT use data annotations in your EF entity classes. Instead, try out the fluent API. It keeps persistence concerns out of the model classes themselves. You can even define the modelbuilder stuff in an entirely different library.
As for having duplicate properties, properties are cheap:
public string MyProp { get; set; }
Not a lot of code, and you may begin to see, the viewmodels and entities need not always be exact duplicates of each other. For example, what if you want to apply [HiddenInput] to a viewmodel, to get it to render as <input type="hidden" />? Would you apply that to the entity? Why? It belongs in the viewmodel (the namespace is even System.Web.Mvc, not System.ComponentModel.DataAnnotations).
As far as duplicating error messages during validation (if you validate the MVC and EF layers separately), you can use resx resources.
As far as freeing db resources, let EF manage that. I find it's best to keep a single DbContext instance per HttpContext. You can open it up using a factory, an OnActionExecuting action filter, Application_BeginRequest, with an IoC container, or whatever. Then dispose context during OnResultExecued, Application_EndRequest, etc. Keeps things simple.

What's wrong with passing Linq2Sql objects to Views?

In a previous question, #Darin Dimitrov answered:
In your case the worst thing is that
you are using your Linq2Sql models
inside your views and that's one of
the worst anti-patterns I see people
doing in ASP.NET MVC applications. You
absolutely should be using view
models. That's what views should be
passed from controllers and that's
what controllers should get from
views.
Why is it so bad to pass Linq2Sql objects as Models?
There are a lot of reasons why it's bad to pass Linq2Sql objects as models to your views and controllers, and it would be relatively difficult to cover all of them in a single answer. So, here are my top 3:
Separation of Concerns - Linq2Sql objects have DAL logic embedded in them, which is a violation of SoC. Also, you will likely want to validate data passed from your views, which should be done in the Model (NOT the controller!). However, if you add this logic to your L2S models then you also violate SoC (not to mention the fact that your validations will be wiped out if you regenerate your L2S models)
Encapsulation - Your L2S classes have a lot of members that your view(s) and controller(s) likely do not need access to. A proper model would encapsulate these members to keep them inaccessible.
Maintainability and Reusability - At some point you may decide you want to change your backing store. If you use your L2S classes as models then you'll end up touching a LOT of code to make that change, whereas if you roll your own models then you'll only have to worry about changing your models and nothing else. Also, not messing with your L2S models (see SoC above) means that they're reusable across projects.
In addition to Brian Driscoll's excellent answer, I would add that with LINQ to SQL or the Entity Framework, you don't always know what values actually exist on the objects you've been given. Let's say your view model included a User object from Linq2Sql. You may be tempted to do something like this:
Messages (<%: Model.User.Messages.Count() %>)
Because the Messages property exists on the user object, it's easy to assume that this is totally fine. However, the results of this action aren't entirely clear.
If you have lazy loading enabled, but the context has been disposed, an exception will be thrown.
If you have lazy loading disabled, you'll probably end up with "Messages (0)"
If you have lazy loading enabled, and the context is active, this will cause every single message associated with that user to get loaded into memory, just to figure out how many there are.
On the other hand, if you used LINQ to generate a ViewModel that contains the information you know you'll need to generate your view, it might look like this:
using (var context = _contextFactory.Get()) {
return (from u in context.Users
where u.UserId == userId
select new UserSummary {Name = u.Name, MessageCount = u.Messages.Count())
.Single();
}
This uses a single SQL query to get all the information you'll need for this view, while ignoring any information you won't need (like the entire contents of the user's inbox). If some future developer wants to add information to this view, they're going to have to ensure it's populated on the ViewModel as part of the data-access logic.
Not only Linq-To-Sql objects, but any entity object should not be exposed to the view.
It reveals your data schema to the end user( a hacker might find it usefull)
It violates the separation of concerns principle in mvc.
When your entity objects lazy load inside the view, it is not much different to have used the data access logic inside the view. So the whole point of layering your application is gone.

Are there any good reasons to put logic (methods) into view Model classes

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.

How to handle view model with multiple aggregate roots?

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.

Resources