I'm using EF with ViewModel and AutoMapper design strategies for an MVC3 application.
I'm wondering if there is a more efficient way of creating the CRUD pages then what I'm currently doing.
My Current Process Involves:
Create the Entity
Create the ViewModel via copy paste then deleted non-required fields
Add the Entity to the Context list
Create a controller via the Visual Studio 2010 create controller wizard page.
I select a Template of Controller with read write actions and views, using Entity Framework.
I choose my model to be my ViewModel instead of my entity.
I select the appropriate context.
Now the part I part I think can be improved, I have to re-write all the CRUD methods to use AutoMapper and the Entity/ViewModel design pattern changing:
return View(db.BlockedUserViewModels.ToList());
into:
IList<BlockedUser> blockedUsers = db.BlockedUsers.ToList();
IList<BlockedUserViewModel> blockedUserVMs = AutoMapper.Mapper.Map<IList<BlockedUser>, IList<BlockedUserViewModel>>(blockedUsers);
return View(blockedUserVMs);
I have to add the same [Authorize] and roles permissions to each controller CRUD option.
This seems way overkill in workload! I'm hoping there a better solution. (I'm coming from Python/Django where it requires a single line of code to create beautiful strong CRUD pages)
It sounds like you can add a service and inject it into your controller. Then you only have to call
var model = _service.GetBlockedUsers();
each time instead of:
IList<BlockedUser> blockedUsers = db.BlockedUsers.ToList();
IList<BlockedUserViewModel> blockedUserVMs = AutoMapper.Mapper.Map<IList<BlockedUser>, IList<BlockedUserViewModel>>(blockedUsers);
This will keep your controllers light and act as a place to keep your crud logic so you don't have to repeat it everywhere.
Also, you can add the [Authorize] attribute to the controller if it applies to every action in the controller.
It really depends on how painful this is for you, but you can always use the MVC scaffolding stuff found in Nuget and written by Steven Sanderson. Investing some time could help you in the long run, but you have to figure out if it's right for you.
http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/
Related
I have to gradually replace an ASP.NET Web Forms application with an ASP.NET MVC3 layered application. Let's take into consideration just the Repository layer.
In my new MVC application I have one project for Data (name MVC.Data) and one for Web.
In the MVC.Data I have an edmx file with the EF classes, which models just the DB table (no views), and a Respository class myRepository which provides methods that perform simple queries.
In the old Web Forms application I have a GridView which is filled using as DataSource an SQL database view.
In order to have the same result in my new MVC3 application, I have two options:
1) Create a Service layer (and project MVC.Services), where I have a method that fill a new class myViewClass which contains all the fields of the SQL DB view and give it to the controller.
2) Create a class within the MVC.Data project which is directly filled by its constructor by using LINQ statements directly against the EF classes.
I read about the factory pattern and the 1st solution seems the most appropriate, however many people always suggest not to create a Service Layer if it is not needed. What is the best choice in this case?
Actually building the view model should be done in a mapping layer. Basically your controller action might look like this:
public ActionResult Index()
{
SomeDomainModel model = repository.GetSomeDomainModel();
SomeViewModel vm = Mapper.Map<SomeDomainModel, SomeViewModel>(model);
return View(vm);
}
The view model is defined in the MVC project as it is a class that is specifically designed to meet the requirements of the given view.
The Mapper.Map<TSource, TDest> method I have shown in my answer comes from AutoMapper which I use in my project but you could define any custom mapping layer you like.
The mapping layer must also be part of the MVC project as it must be aware of both your domain models and your view models in order to perform the mapping.
As far as the service layer is concerned, you could use one when you have some complex business operations which could be composed of multiple simple repository calls. But some might argue for the existence of a service layer at all. I think that both approaches have their pros and cons that must be evaluated when designing a system and most importantly take into consideration the specific context and scenario you are designing.
i am a complete newbie to the entity framework,mvc just started with it 3 weeks ago.
From then i have been beating around the bush searching for the right approach.the more i dig the more i get lost...i am afraid that i could not proceed any further with using entity framework in mvc
I m lost and frustrated :(
what i have been trying to do is to use entity framework for the MVC application.For that i have started with creating an School.edmx file(which has School.Designer.cs automatically created for it.I dont have any POCO or any others just plain edmx with designer class).Then through some searching i have found that its bad practice to use entity object as model for view.....
Now the real thing started i have made a viewmodel for an entity object.The thing is i dont really get why i have to use a repository and why do i have to map my entity objects and viewmodel objects.Everytime i search why i have to map i get some links saying how to use automapper and the more i search about repository the more i get lost .i dont even understand it.why do i have to map ...??? and why do i have to use repository.
And now the other thing i ask repeatedly to myself is why do i have to write data annotation again in the Viewmodel class when i have already data annotated it in my designer.cs file (like [Required],[Email] and other annotations)..? WHY to write them again!! (If i dont mention them in viewmodel i dont see the annotations working). Duplication of annotation...?
I am lost and i dont even know where i m now
someone give me the right path to follow
Yours Sincerely,
Lost & Confused Newbie
Don't Fret!
Entity Framework is a big beast of a framework based on another beast of a framework: ADO.NET. It's very difficult to truly understand Entity Framework apart from understanding ADO.NET.
That being said, Entity Framework is the perfect tool in some scenarios. However, you (like many of us) seem to have a disconnect about the roles of EF, ASP.NET MVC, and a Repository.
The thing is, you don't need a repository. You don't even need a view model. You don't need EF. And you don't even need ASP.NET MVC. All of these tools are used to make specific jobs easier. None of them have direct ties to each other, and any of them can be used independently of each other.
A Repository: is used to put certain objects into some persistent place, so that you can get them later. That's really all it is.
ASP.NET MVC: Is an HTTP Handler that takes the requested URL and instantiates a controller class which in turn serves up views. The views display some model, and because the views are interactive, they allow the user to send yet another request, starting the whole thing over again. Because this process is (intentionally, but not necessarily) stateless, some sort of persistence is required. This persistence can be a file on the server, a file database, or in most cases a relational database.
Entity Framework: sits on top of ADO.NET (Microsoft's relational database abstraction framework), and allows you to map objects from a graphical (in memory) form to a relational (in-database) form, and back again. The idea is to allow the developer to easily map objects to and from the database. However, this is not a simple process, and because you're not directly interacting with the database (be it via ADO.NET or not), there is some inherent complexity. One of those complexities is the display of the information.
View Models (asp.net mvc view models): allow models to be displayed in various forms. For instance, we may have a "scholastic record" table, and a "person" table, and together they might form a "student". Because our entities are "ScholasticRecord" and "Person", we cannot (as) simply display the information on the view. For this reason, we create a view model to combine and display the information as a "Student".
View Models also prevents us from accidentally calling "lazy" methods on our entities while in the view, which might query the database. This isn't bad, but it could get confusing, because our view is doing repository-like work (which isn't very [S]OLID).
TLDR;
The reason you're having trouble is probably because you're trying to do everything at once. I would suggest using the tools you know, in addition to maybe one or two that you do not. Try using Entity Framework and ASP.NET MVC together, but don't worry about the Repository pattern just yet. It can be difficult to use EF with a Repository, unless you have a lot of experience with either or both.
ASP.NET MVC Tutorials with Entity Framework:
http://www.asp.net/mvc/tutorials/mvc-music-store
(notice how they use models directly in the view, sometimes)
The thing is i dont really get why i have to use a repository
MVC helps you write code that has a clear separation of concerns. In this case, the repository is meant to how the application interacts with the data storage for a specific entity. If you want a Student entity you call StudentRepository.GetEntity(). If you want to save to save you call the StudentRepository.SaveEntity(Student student).
Why do i have to map my entity objects and viewmodel objects.Everytime i search why i have to map i get some links saying how to use automapper and the more i search about repository the more i get lost.
While you can use these entities directly in your view for simple cases, the problem comes up when you have more complex views - composite views that may need multiple entities, views that need to expose only a subset of an entity or even a subset of multiple entities. So yes, you can just expose your entity directly but I find it easier just to create a separate view model.
Automapper is used to help map from view model to entity. So, instead of writing a lot of
entity.Name = viewModel.Name;
entity.Age = viewModel.Age;
...
Automapper is used to automatically map these properties.
And now the other thing i ask repeatedly to myself is why do i have to write data annotation again in the Viewmodel class when i have already data annotated it in my designer.cs file (like [Required],[Email] and other annotations)..?
You should specify validation logic specific for each view in the view model so that if validation fails at the controller it can stop processing instead of continuing. Even though mapping your view model to an entity and trying to save would be prevented by the entities data annotation, I find it clearer to look at a view and its view model to understand what's going on instead of going from view to view model to entity.
Update:
Take a look at ASP.NET MVC View Model Patterns and How we do MVC – View models. I found them both useful when trying to understand view models.
There are a lot of articles about using MVVM patterm for ASP .NET MVC. For example, it is http://blogs.microsoft.co.il/blogs/helpercoil/archive/2010/08/28/asp-net-mvc-and-the-mvvm-pattern.aspx.
There is only one question for me. We have a lot of ViewModels for one Model. How can I fill Model properties automatic by using viewModel object? How to make automatic property mapping?
I use Entity Framework.
For example, I have model Test with the following properties:
id
name
title
idUser
idCompany
I made ViewModel for my task. This ViewModel (TestUserViewModel) uses for simple user with the following properies:
- id
- name
- title
For example, user edit an existing test. As the result, we have an object with type TestUserViewModel. I want:
synchronize Model object and ViewModel.
save the default valies for idCompany, idUser - for properties, which were excluded from current ViewModel.
use some automatic stuff - it may be something like ApplyCurrentValues. I really don't want to write a lot of following code:
modelObj.name=viewModelObj.name;
modelObj.title=viewModelObj.title;
Using System.Reflexion for this looks like bad, too.
So, how to do it?
If you don't want to write a lot of mapping code from one object to another you might want to look into mapping tools like AutoMapper http://automapper.org/
Having said that, as #Darin Dimitrov pointed out, you should review your architecture too. If you are doing ASP.NET MVC you should become more familiar with MVC rather than MVVM. As you read more about how to use MVC you are going to start seeing the use of "viewModels". Keep in mind that these "viewModels" in MVC have nothing to do with "VM" in "MVVM".
I am quite new to MVC. I am having the following questions, please help me clarify those questions, thanks a lot.
Q1. Where should I populate my view model? e.g. My view model is very big, and contains a lot of the dropdown listbox, multi select list and the other few complex objects. I am currently populate them inside the view model self, by passing the model through the constructor, and load all the object data within the constructor. I also see my college populate the viewmodel inside controller. so I am confusing now, coz lots of people suggest to keep the controller small and skinny.
Q2. We are using the linq2sql as data access layer, should I use the table entity in my viewmodel instead of creating separate model class? Expert said it's bad, but if create seperate model class, I basically repeat them and I also need to copy those value to linq 2sql entity every time when I want to persist data, it's not that fun, too much work.
lots of people suggest to keep the controller small and skinny.
Yes. What people mean is that the controller should not contain any logic, except for model <-> view mapping. With model I mean the "M" in MVC.
Q2. We are using the linq2sql as data access layer, should I use the table entity in my viewmodel instead of creating separate model class? Expert said it's bad, but if create seperate model class, I basically repeat them and I also need to copy those value to linq 2sql entity every time when I want to persist data, it's not that fun, too much work.
No. You should not. Read my answer here: ASP.NET MVC Where to put custom validation attributes
Use a mapping framework for the model -> viewmodel conversion.
Update:
From what I understand, you suggest to assembly the viewmodel inside the controller (I mean call the business layer or repository to get my data) and use controller to call the business logic dealing with the data, am I right?
yes. The controller is really a glue between your business layer / repositories and your views. The views (and view models) should know nothing about them and the business layer / repositories should know nothing about the controller/view.
The controller was created for just that purpose. To create an abstraction between the user interface layer and the lower layers. Hence the only code that should exist in the controller is to make that possible (and therefore following the Single Responsibility Principle)
If you start adding that logic into your view models you start to add coupling between the lower layers and the user interface layer. Doing any changes in the lower layers will therefore also affect all your view models (instead of just the controller
your viewmodel should be a poco, and should most certainly not be handling the mapping of the model. if you don't want to map your model to your viewmodel in the controller i would suggest you look at something like automapper. it makes it easy.
once you've mapped from your model to your viewmodel, any extra properties that need to be set such as your lists should be set in the controller.
as i stated previously, definitely don't tie your viewmodel to your current orm or table structure. you never know what might need to be refactored, and if you can handle it via an automapper mapping instead of changing your view and viewmodel then you've saved yourself a significant amount of time.
From inside to outside, these are our MVC app layers:
MS SQL / Tables / Views / Stored Procs
Entity Framework 4.1 (ORM) with POCO generation
Repository
Service (retrieve) and Control Functions (Save)
Routing -> Controller -> Razor View
(client) JQuery Ajax with Knockout.js (MVVM)
Everything is fine until I need to create a single ViewModel for step 5 to feed both the Razor view as well as the JSON/Knockout ViewModel:
Header that includes all Drop down list options and choices for the fields below
Items - an array of whatever we send to the client that becomes the ViewModel
Since the Controller won't have access to the Repository directly, does this mean I create a service for each and every view that allows editing content? I'll need to get the POCO from the repository plus all options for each field type as needed.
It just seems redundant to create separate services for each view. For example, a viewModel to edit an address and a separate viewModel to edit a real estate property that also has an address. We could have a dozen forms that edit the same address POCO.
To make this question easier to answer, is allowing the Controller direct access to the repositories a leaky abstraction?
Well, so are your controllers going to have code that translates POCOs from Entity Framework into separate view model objects?
If so, then you should move that code to a separate class, and follow the single-responsibility principle. Whether that class is in the "service layer" or not is up to you. And whether you use AutoMapper or not is up to you. But these kind of data mappers should not be part of the controller logic; controllers should be as dumb as possible.
OK, now let's ignore the data mapping problem, and pretend you could always use your POCOs directly as view models. Then you would still want a service layer, because it would translate between
userService.GetByUserName("bob")
in your dumb controller, and implement that in a specific manner by returning
userRepository.Users.Single(u => u.UserName == "bob")
Putting these together, your UserController ends up taking in IUserService and IUserDataMapper dependencies, and the code is super-dumb, as desired:
public ActionResult ShowUserPage(string userName)
{
var user = userService.GetByUserName(userName);
var viewModel = userDataMapper.MakeViewModel(user);
return View(viewModel);
}
You can now test the controller with stubs for both dependencies, or stub out IUserDataMapper while you mock IUserService, or vice-versa. Your controller has very little logic, and has only one axis of change. The same can be said for the user data-mapper class and the user service class.
I was reading an article this morning that you might find somewhat illuminating on these architectural matters. It is, somewhat condescendingly, titled "Software Development Fundamentals, Part 2: Layered Architecture." You probably won't be able to switch from a database application model to the persistent-ignorant model the article describes and suggests. But it might point you in the right direction.
i personally always inject the repository/repositories into the controller. i'm not sure why you would want to have a service layer between the repository and the controller. if anything you would use specifications.
once you've done that, check out automapper. its a mapper that, once properly configured, can map your domain model to your viewmodel, and back again.