At the start of the development I faced with problem called "an impedance mismatch between domain model and the view". To solve this problem I decide to use ViewModel pattern - for every view (that is strongly typed) we create viewmodel class. But where is the validation logic is locate - in viewmodel classes or in our domain model objects? And where we need to perform operations to query database - in controller action, and then populate viewmodel or straight in viewmodel?
Thank you.
You should have validation logic for the viewmodel. This is what the view sends and what should be validated. As far as populating the viewmodel is concerned here's how to proceed: write a repository which queries the database and returns models. Then map those models to viewmodels (AutoMapper can help you here). Finally return viewmodels to the view. This also works the other way around: the users POSTs some data to a controller action as the form of a viewmodel which once validated is mapped back to a model and passed to the repository for update.
As an alternative to Data Annotations you may take a look at FluentValidation for validating your view models. It integrates nicely with ASP.NET MVC.
Related
I have a edmx model done by Database First and generating the DBSet with the VS tools. I extended with partials the classes to add dataannotation validation to it.
I am receiving on my controller the view model which I am manually controlling the validation of fields. So eventhough I have a required field on my partial class, I am removing it once in my controller ModelState.Remove("pasajeros[" + count + "].numResidencia"); because of some conditions.
Before, I was using LINQTOSQL and I had no problems. But now Entity framework is not honoring my customization of ModelState.
How do i propagate or GO about this issue with EntityFramework?
thanks
Keep your view models and Entity models separate. Put your validation annotations on your view models. Then use a tool like Automapper to map the Entity to ViewModel fields for you.
On edit you validate your view model then update your Entity fields which you then save.
I have read that my models should be just dumb containers for data and that kind of appeals to me.
If this is the case then my understanding is that controllers make calls to the Repository which will just fill up the models and pass them back like so.
using (var userRepo = new UserRepository())
{
var users = userRepo.GetAll();
return View(users);
}
If I want to add a method like AlertUserOrderHasBeenRecd() where would I put it?
If I put it into the Repository then the Repository is doing more than just Data Persistence.
If I put it into the Model then the model is no longer a dumb data container.
I could also add an additional class that is passed in an order model and a user model and takes an action without knowing anything about EF.
Or something else.
Is there a generally accepted best way of handling this?
This method could be defined in a service layer. The service layer depends on the repository because it contains business operations which could be composed of multiple CRUD operations from the repositories. Then your controller will take the service layer instead of a repository and invoke the business method on it.
As an alternative to introducing yet another abstraction layer to your application you could favor query objects over repositories.
I've had very nice result separating Models and ViewModels. The ViewModels are just the dumb containers for data (DTOs). The Models are the business layer (the business of the UI). So, the result is:
Controller: handles the navigation through the site.
Models: Fills and process the ViewModels requested by the Controller.
ViewModel: DTO's with data that will be represented.
View: The visual representation of the data in the ViewModel.
In this architecture your method will be in the Model.
I was reading this tutorial for MVC3 with Linq to Entities using Model First.
http://msdn.microsoft.com/en-us/data/gg685489.aspx
A quote from the article states
Our controllers will use the BlogDataEntities to retrieve data for us.
In a more advanced application, you should separate logic further and
would not be working with the BlogDataEntities directly from the
controller.
What is the general structure of this other layer between the entities and Controller in an MVC application? What is the purpose?
I usually have a bastardized ViewModel (see http://en.wikipedia.org/wiki/Model_View_ViewModel) which contains the business logic, can fetch/save from EF and is what the view is bound to. The controller doesn't do much but instantiate the viewmodel and depending on the controller action, call a method within the view model.
Some people might break that up even further and have a full blown ViewModel which has no logic in it,just data. A business layer with all of the logic and the ability to move data from EF to the ViewModel and vice-versa.
In the article "BlogDataEntities" is not the name for some specific entity classes (what the name suggests) but the name of the DbContext.
I guess it means that you would try to hide that you work with EF by not instantiating the DbContext, but by using a repository-implementation like this
http://msdn.microsoft.com/en-us/data/ff707264#_Toc261428890
User have to populate multistep questionnaire web-forms and step messages depend on the option chosen by user at the very beginning. Messages are stored in web.config file. I use asp.net mvc project, strong typed views and keep business logic separated from controller in static class. I don't want to make business logic dependency on web.config.
Well, I have to insert message into view that depends on session value.
There are at least 2 options how to implement this:
View model has property that is populated in controller/businessLogic and rendered in view like <%: Model.HelpMessage1 %>. I have to pass web.config values from controller to businessLogic that makes business logic methods signature too complex.
Create static helper class that is called from view like <%: ViewHelper.HelpMessage1(Model.OptionChosenAtTheVeryBeginning) %>. But in this case logic what to show seems to be separated into two classes: business logic & viewHelper.
What will you suggest?
Thank you in advance!
As Adrian pointed out, your problem belongs in the business domain. Why not get the message, and put it into a view model along with your other data/models.
It appears that deciding which messages have to be displayed and / or how models are assembled from these messages is part of your business logic. How about storing the messages in your business layer and let your business layer generate the model with populated messages?
Say I have an object that gets some data from HttpPost and some from the database. I think I want to allow the ModelBinder to go to the database/repository for the that data missing from the post. In practice, is this a good or bad idea?
I've decided to edit my original answer given my thinking on these types of things has evolved since early 2010.
In my original answer, I basically expressed that, while my instincts told me you shouldn't do this, I was uncomfortable saying we shouldn't without being able to articulate why.
Now, I'd recommend against this on the grounds that the responsibility of a Model Binder is to translate a user request into a Request Model and that retrieving data outside of what can be derived from the request goes beyond this scope of responsibility.
I would say a bad idea. The idea of the model binder is that it takes the parameters from the request and creates your model from those. If your model binder, behind the scenes, fills in some of the details from the database this breaks the paradigm. I'd much rather expose the database call in my controller by explicitly fetching the required extra data from the database directly. Note that this could be refactored into a method if used frequently.
I think this is perfectly fine and use this technique all the time.
The only arguments against are very pedantic and amount to arguing over philosophy. IMHO you can put "fill in missing posted data" code into you MVC app as a method in your base controller vs. method in you ActionFilter vs method in you ModelBinder. It all depends on who get what responsibility. To me the model binder can do a lot more than simply wire up some properties from posted values.
The reason I love doing database calls in my modelbinder is because it helps clean up your action methods.
//logic not in modelbinder
public ActionResult Edit( KittyCat cat )
{
DoSomeOrthagonalDatabaseCall( cat );
return View( new MODEL() );
}
vs.
//logic in model binder
public ActionResult Add( KittyCat cat )
{
return View( new MODEL() );
}
It violates the way MVC is supposed to work. ModelBinder is for binging Models from the data that comes from the view. Populating missing info from the database is something that is supposed to be handled by the controller. Ideally, it would have same data layer/repository class that it uses to do this.
The reason it should be in the controller is because this code is business logic. The business rules dictate that some data may be missing and thus it must be handled by the brains of the operation, the controller.
Take it a step further, say you want to log in the DB what info the user isn't posting, or catch an exception when getting the missing data and email admins about it. You have to put these in your model binder this way and it gets more and more ugly with the ModelBinder becoming more and more warped from its original purpose.
Basically you want everything but the controller to be as dumb and as specialized as possible, only knowing out how to carry out its specific area of expertise which is purely to assist the controller.
I would say, no.
Here's why: It would create a dependency on your database for testing your controller actions that would not be easy to abstract out.
I would say it is ok. The argument that creates dependency to database is a false argument for 2 reasons:
1- Database access should be abstracted via repository interfaces. Repository interfaces are part of the domain model and their implementation is part of the infrastructure/data access layer. So there is no dependency to the database.
2- Model Binders and Controllers are both part of presentation layer implemented using ASP.NET MVC Framework. If Controllers are allowed to access database using repository interfaces, how come Model Binders are not allowed?
Also, there are situations that you'd "better" fill the missing data in your model from Model Binders. Consider the scenario where you have a drop-down list on your view. The first time the view is loaded, the drop-down list is populated. The user submits the form but the validation fails. So you'll need to return the form again. At this stage, you'll have to re-populate the list in the Model for the drop-down list. Doing this in Controller looks ugly:
public ActionResult Save(DocumentViewModel viewModel)
{
if (!ModelState.IsValid)
{
viewModel.Categories = _repository.GetAll();
return View(viewModel);
}
}
I believe the initialization of Categories here is ugly and like a code smell. What if you had a few properties that needed to be filled out from database? What if you had more than 1 action that had DocumentViewModel as an argument? You'd have to repeat this ugly step over and over. A better approach is to fill all the properties of the model using the Model Binder and pass it to the Controller. So the object that is passed to the controller is in a "consistent" state.