I am attempting something very ambitious on asp.net MVC 3 backed with C sharp 4.0 . Without further trash talk I will get
to point .
I have to build a web application in which I can make simple forms ( a CMS type application) .
The usual approach we take is to design the form in the cshtml , and back it with a viewmodel.
The viewmodel takes care of the validation rules , the error messages etc. Now what I have to do is to allow the user
to create a form .
I sat to write down on a piece of paper on how would i go about this . I would be able to generate a form , based on
some user inputs , but where I have reached a deadend is , how would i create a viewmodel at runtime ?
for example if in my database , I konw that a form called "Registration" , has a control "TextBox" , that would take a String
and is Required
public class RegistrationViewModel
{
[Required(ErrorMessage="Cant let this go buddy")]
public String Name {get;set;}
}
I wish to strongly type my views with such viewmodels , but I am not sure how to dynamically construct a C# class based on some data that I have inside the database.
I am not so sure if C# has some constructs to achieve the purpose , I am just new with the .net platform .
I want to know if there is any approach by which I can generate some viewmodels from the database at runtime , and strongly type my views with them .
Thanks
Well there is AssemblyBuilder class that you can use for runtime types.
Related
I have almost completely understood the MVC pattern, but there is one thing that still confuses me:
Let's say - for the purpose of this example - I have got a controller, a model and 5 views. Whenever the model changes, I would like to (optimally) change a (proper) subset of these 5 views as a result of changes in the model.
What would be the right way to do it ?
My understanding of MVC as of now is that the model should not know anything about either controller or view. Does that apply to the view as well ? I.e. does the view also not know about controller AND model ?
Based on the assumption above, the proposal for my MVC program with the given requirements would structurally look something like this:
Pseudocode:
OPTION 1
MODEL
//Random data, no references to either controller or view
notifyObserver(){
observer.modelChanged();
}
CONTROLLER
reference MODEL
reference VIEW
var model;
var view1;
var view2;
var view3;
var view4;
var view5;
createController(m,v1,...,v5){
model = m;
view1 = v1;
.
.
.
view5 = v5;
}
modelChanged(){
view1.updateView(model.someVariable);
view4.updateView(model.someVariable);
}
VIEW
//no references to either model or controller
//some visual elements
updateView(var someVariable){
myVisualElement.change(someVariable);
}
TESTCLASS
main(){
create view1;
create view2;
.
.
.
create view5;
create model;
create controller(model,view1,...view5);
model add observer(controller);
}
So what I am basically doing with this, is letting the controller know about everything, while both view and model act completely independently. In this case, the CONTROLLER is the only one who gets notified when something changes in the model. It will then go ahead and change its views accordingly.
OPTION 2
So the VIEW would basically have a property/variable called model, that I will pass in with the constructor like this:
TESTCLASS
main(){
create model;
create view1(model);
create view2(model);
.
.
.
create view5(model);
create controller(model);
model add observer(view1);
.
.
.
model add observer(view5);
}
This way, all the views have references to the model and are notified by the model as soon as something changes.
I am confused because I am not sure which is the right approach... I hope you can help me understand this once and for all.
That's hard to catch what's the best solution for you and what you are actually asking for.
Which technology do you use, as dependently on a platform, there might be some specific nuances on MVC?
MVC basically don't have anything like observer.modelChanged and if you do use it, that adds certain limitations/possiblities on the inplementation details.
For instance, if you use mobile applications, you would rather have that MVC transformed to MvvM (Model-View-ViewModel) (where ViewModel would act rather as a Controller) and in that case the "Controller" would know only about Model, and View would know only about Controller (representing its Model partially).
If you use web application ((ASP.NET) MVC), you would have a Controller, which passes Models to Views (without knowing how actually the View works). Views would also know Model and adapt itself to it, but also getting in touch with Controller. At the same time, Model would not know about anyone of mentioned.
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.
We are working on an ASP.NET MVC 3 using ext.net and EF 4.
Data model is mapped using EF4.
Views’ content is rendered from customizable XML files.
Example: Within one view, I can display fields that are related to both objects “customer” and “order”, so from this view I can modify the customer data and also add a new order.
How can we bind the view to the custom model that contains 2 objects (customer and order)? Using non strongly typed views will require a source code that will check all different possibilities (If I remove/add a field to display from the XML file, object constructor and CRUD operations parameters will change also.
We are wondering how can we handle such dynamic application?
Is this a common issue that was raised before? Or is there any solution to use dynamic views bound to custom model (object, xml, etc.)?
Your help is very appreciated, please enlighten me.
Based on what you replied to my comment, I can defenitely say that you need strongly typed views. That said, you decide what the model of your view is. If your view needs to manage users and orders at the same time, you can make a class like this:
public class MyCustomViewData
{
public IEnumerable<User> Users {get;set;}
public IEnumerable<Order> Orders {get;set;}
}
and then strongly type your view to MyCustomViewData and you're set. My example is oversimplified but I think you can get the point.
Unless I'm missing something, I believe the normal way round this would be to strongly type your view to say 'user' and then on the user object, define a property which is a collection of 'orders'.
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/
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.