Nhibernate/MVC: Dealing with lazy loaded collections in View - asp.net-mvc

I'm currently using an attribute based approach to nhibernate session management, which means that the session is open for the duration of the Action method, but is closed once control is passed to the View.
This seems like good practice to me, however I'm running in to problems with lazy loaded collections. (This is complicated by the fact that some collections seem to be lazy loading even though they have Not.LazyLoad() set in the fluent mapping).
As I see it, my options are:
Change my ISession management strategy and Keep the session open in the View
Make better use of ViewModels (I'm currently not using them everywhere).
Eager load all of the collections that are causing problems (maybe paged) (fluent problem not withstanding)
1 seems a bit wrong to be - but may be the 'easiest' solution. 2 is probably the proper way to go, but in some cases ViewModels seem slightly redundant, and I'm loathed to introduce more classes just to deal with this issue. 3 seems to be a bit of a dirty fix.
What do you think?

The best way to handle this (in my opinion anyways) is to introduce a service layer in between your UI and your repositories; It should take care of loading everything needed by the view and pass off a flattened (and fully populated) dto to the view.
Often, I go one step further and map the dtos returned from the service layer to view models, which often need to contain data that is very view-specific, and not appropriate for inclusion into the dtos coming from your service layer. Remember, Automapper is your friend when it comes to situations like this.
Using an open-session-in-view pattern is still perfectly acceptable, just don't have your views invoking lazy loading on entity models - this is almost always a horrible idea.

consider your current usage as making implicit database operations. The object is sent to the View but the object contains proxies which when touched will try to return the data, and that requires a database operation.
Now,
extending the ISession life including the View, its not wrong, as long as you are not doing explicit database calls...
i wouldn't know about that
This is actually the proper way regardless of the session EOL: you should try to do as less queries as possible per request and nhibernate gives you that ability via lazyless loading, futures, multihql/criteria etc.
note: although you may have mapped a collection as not lazy loaded it matters also How you query and get your desired result set. eg if you are using HQL then use a fetch join

I don't think there's anything wrong about the first approach, and it will be the easiest to implement.
Session per request is a well known session management pattern for NHibernate.

Related

Why do we use ViewModels?

I have recently started working as a web developer. I work with ASP .NET MVC 4 and NHibernate.
At my work-place, we are strictly made to use viewmodels to transfer data to and fro between a controller and a view. And the viewmodels are not supposed to contain any object of a model.
I understand that it is a sort of a tier between the controller and the view.
But I find it repetitive and redundant to write a viewmodel class even if we can directly send the model's object to the view (in most cases).
For example, if i want to display an order i can do this in the controller's action -
return View(Repository.Get<Order>(id));
But instead, I have to write a viewmodel, fill it with the fetched order and then pass it to the view.
So, my question is, what purpose does writing viewmodels serve when we can use the model's object as it is?
For smaller projects, you're right. I hear your argument and sympathise - however there are good reasons for this, drudged and repetitive work, especially in larger and more complicated applications:
It's essential to perform all processing within the Controller's action. However in the example you've given, the Repository.Get method might return a lazily-evaluated IQueryable object, which would mean the DB wouldn't be hit until the View is evaluated. For a variety of reasons this is bad. (A workaround is to call .ToList while still in the controller).
"A view should not contain any non-presentational logic" and "You should not trust the View" (because a View could be user-provided). By providing a Model object (potentially still connected to an active DatabaseContext) a view can make malicious changes to your database.
A View's data-to-display does not always map 1:1 with its Model's data, for example consider a User Details page:
A User's EF Model object represents its entity in the database, so it probably looks like this: User { UserId, UserName, PasswordHash, PasswordSalt, EmailAddress, CreatedDate }, whereas the fields on a "User details" page are going to be User { UserId, UserName, Password, ConfirmYourPassword, EmailAddress }, do you see the difference? Ergo, you cannot use the EF User model as the view model, you have to use a separate class.
The dangers of model manipulation: if you let ASP.NET MVC (or any other framework) do the model binding to the incoming HTTP POST Request then (taking the User details example above), a user could reset anyone's password by faking the UserId property value. ASP.NET will rewrite that value during binding and unless you specifically sanitize it (which will be just as drudgeful as making individual ViewModels anyway) then this vulnerability will remain.
In projects with multiple developers working in a team situation, is is important that everything is consistent. It is not consistent to have some pages using bespoke ViewModels but other pages using EF Models because the team does not share a concious mind, things have to be documented and generally make-sense. For the same reason a single developer can get away without putting excessive XML documentation in his source code, but in a team situation you'll fall apart if you don't.
There is a slight workaround in your case I'll share with you, but please note the preconditions:
Your views can be fully trusted
Your views contain only presentational logic
Your application is largely CRUD
Your views correspond 1:1 with each EF entity model (i.e. no JOINs)
Your views only deal with single Simple models for POST forms, not Complex models (i.e. an object graph)
...then you can do this:
Put all one-way, non-form-related data into your ViewData collection, or the ViewBag in MVC 4 (or even a generic ViewData<T> if you're hardcore). This is useful for storing HTML page titles and sharing data with Master pages.
Use your fully-evaluated and loaded EF models as your View<TModel> models.
But use this approach with caution because it can introduce inconsistency.
Well, i'm starting to think the pragmatic approach to every problem is required and not to just subscribe to the purist architectural standards out there. Your app may be required to run in the wild and be maintained by many developers serving a large set of client etc. and this may direct or drive your architecture.
The ViewModel is essential when you want a separation of concerns between your DomainModel (DataModel) and the rest of your code.
The less dependencies you have between the Model, View and Controller the easier down the line it will be to make changes to the DomainModel without breaking the interface contracts in the View and Controller etc. etc. But once again it's something to be pragmatic. I like the approach as code re-factoring is a big part of system maintenance - refactoring may include a simple spelling mistake on a property of a Model - that change could ripple through the code to the Contract level if the dependencies are not separated; for example.
The ViewModel is used to translate the data between your DomainModel and you Views
A simple example of a datetime stored in Informix has to be translated to a .Net DateTime. The ViewModel is the perfect place to do this translation and does not force you to put translation code in all sorts of unwanted places.
One attribute of a good design [of anything] is the ability to replace or modify a part of the implementation with little or no affects to the rest of the parts of the system. But this takes effort and time to achieve - it's up to you to find that practical balance between a perfect design and a design that is just enough
But yeah, there are many other good reasons to use certain patterns - but the bottom line is this:
Nothing forces you to use ViewModels... ASP.NET MVC won't force you. Take advice from the pragmatist inside you.
If you use same Models as your ViewModels, your application should be very small and simple and should contain only CRUD operations. But if you are building large or enterprise applications with large teams (with two or probably more developers), you should have concepts like Dependency Injection, Services, Repositories, Façades, Units of Work, Data Access Objects etc.
To simplify your mapping needs between Models and ViewModels, you can use AutoMapper
https://github.com/AutoMapper/AutoMapper
or install with nuget
Install-Package AutoMapper
According to me, it is essential to have one more layer(ViewModel) on top of Model layer for complex applications that performs most of the CRUD operations because it has following advantages:
To establish loose coupling between Model and Controller. So that any DataModel related modifications will not be affected to Controller.
If you've implemented your application's ViewModel layer correctly
by providing maximum level of IOC(Inversion of Control) via
DI(dependency Injection using Unity/other frameworks), etc., it will
also help you to MOQ your ViewModels(dependencies) for testing only
the controller's logic.

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.

ASP Mvc Nhibernate Issue

I am experiencing some bizarre problems with Nhibernate within my MVC web application.
There is not 1 consistent error, I keep getting loads of random ones:
Transaction not successfully started
New request is not allowed to start because it should come with valid transaction descriptor
Unexpected row count: -1; expected: 1
To give a little context to the setup, I am using Ninject to DI the sessions and other Nhibernate related objects, currently I am using RequestScope however I have tried SingletonScope. I have a large and complicated data model, which is read out as a whole, but persisted back in separate parts, as these can all be edited and saved individually.
An example would be having a Customer object, which contains a address object, a contact object, friends object, previous orders object etc etc...
So the whole object is read out, then mapped to the UI domain models and then displayed in different partials within the page. Each partial can be updated individually via ajax, so you may update 1 section or you could update them all together. It seems mainly to give me the problems when I try to persist them all together (so 2-4 simultanious ajax requests to persist chunks of the model).
Now I have integration tests that work fine, which just test the persistence and retrieval of entities. As a whole and individually and all pass fine, however in the web app they just seem to keep throwing random exceptions, and originally refused to persist outside of the Nhibernate cache. I found a way round this by wrapping most units of work within transactions, which got the data persisting but started adding new errors to the mix.
Originally I was thinking of just scrapping Nhibernate from the project, as although I really want its persistance/caching layer, it just didnt seem to be flexible enough for my domain, which seems odd as I have used it before without much problem, although it doesn't like 1-1 mappings.
So has anyone else had flakey transaction/nhibernate issues like this within an ASP MVC app... I know this may be a bit vague as the errors dont point to one thing, and it doesn't always error, so its like stabbing in the dark, but I am out of ideas so any help would be great!
-- Update --
I cannot post all relevant code as the project is huge, but the transaction bit looks like:
using (var transaction = sessionManager.Session.BeginTransaction(IsolationLevel.ReadUncommitted))
{
try
{
// Do unit of work
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
}
Some of the main problems I have had on this project have stemmed from:
There are some 1-1 relationships with composite keys, but logically it makes sense
The Nhibernate domain entities go through a mapping layer to become the UI domain entities, then vice versa when saving. Problem here is that with the 1-1 mappings, when persisting the example Address I have to make a Surrogate Customer object with the correct Id then merge.
There is ALOT of Ajax that deals with chunks of the overall model (I talk like there is one single model, but there are quite a few top level models, just one that is most important)
Some notes that may help. I use windsor but imagine the concepts are the same. Sounds like there may be a combination of things.
SessionFactory should be created as singleton and session should be per web request. Something like:
Bind<ISessionFactory>()
.ToProvider<SessionFactoryBuilder>()
.InSingletonScope();
Bind<ISession>()
.ToMethod( context => context.Kernel.Get<ISessionFactory>().OpenSession() )
.InRequestScope();
Be careful of keeping transactions open for too long, keep them as short lived as possible to avoid deadlocks.
Check your queries are running as as expected by using a tool like NHProf. Often people load up too much of the graph which impacts performance and can create deadlocks.
Check your mappings for things like not.lazyload() and see if you actually need the additional data in the queries and keep results returned to a min. Check your queries execution plans and ensure adequate indexes are in place.
I have had issues with mvc3 action filters being cached, which meant transactions were not always started, but would attempt to be closed causing issues. Moved all my transaction commits into ActionResults in the controllers to keep transaction as short as possible and close to the action.
Check your cascades in your mappings and keep the updates to a minimum.

When is it right to use ViewData instead of ViewModels?

Assuming you wanted to develop your Controllers so that you use a ViewModel to contain data for the Views you render, should all data be contained within the ViewModel? What conditions would it be ok to bypass the ViewModel?
The reason I ask is I'm in a position where some of the code is using ViewData and some is using the ViewModel. I want to distribute a set of guidelines in the team on when it's right to use the ViewData, and when it's just taking shortcuts. I would like opinions from other developers who have dealt with this so that I know my guidelines aren't just me being biased.
Just to further Fabian's comment; you can explicitly ensure viewdata is never used by following the steps outlined in this article. There's really no excuse not to use models for everything.
If you have no choice but to use ViewData (say on an existing project); at the very least use string constants to resolve the names to avoid using 'magic strings'. Something along the lines of: ViewData[ViewDataKeys.MyKey] = myvalue; Infact, I use this for just about anything that needs to be "string-based" (Session Keys, Cache Keys, VaryByCustom output cache keys, etc).
One approach you may wish to consider as your views become more complex, is to reserve the use of Models for input fields, and use ViewData to support anything else the View needs to render.
There are at least a couple of arguments to support this:
You have a master-page that requires some data to be present (e.g. something like the StackOverflow user information in the header). Applying a site-wide ActionFilter makes it easy to populate this information in ViewData after every action. To put it in model would require that every other Model in the site then inherit from a base Model (this may not seem bad initially, but it can become complicated quickly).
When you are validating a posted form, if there are validation errors you are probably going to want to rebind the model (with the invalid fields) back to the view and display validation messages. This is fine, as data in input fields is posted back and will be bound to the model, but what about any other data your view requires to be re-populated? (e.g. drop-down list values, information messages, etc) These will not be posted back, and it can become messy re-populating these onto the model "around" the posted-back input values. It is often simpler to have a method which populates the ViewData with the..view data.
In my experience I have found this approach works well.
And, in MVC3, the dynamic ViewModels means no more string-indexing!
I personally never use ViewData, everything goes through the Model, except when im testing something and i quickly need to be able to see the value on the view. Strongtyping!
In terms of ASP.NET MVC 2, ViewModel pattern is the preferred approach. The approach takes full advantage of compile time static type checking. This in combination with compiling mvc views will make your development work-flow much faster and more productive since errors are detected during build/compile time as opposed to run time.

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