ASP.NET MVC Multiple Partial Views in 1 View Model Binding - asp.net-mvc

I am having trouble dealing with user registration in ASP.NET MVC3 Model Binding.
Basically, I have a ViewModel that consists of UserDetails (name, identification, dob and other things) and a reusable ViewModel, Address.
So, UserDetails class will also carry an Address class.
Then, I created a partial view with model binding to Address ViewModel so that this too can be reusable.
In view, this is what I did: #Html.Partial("CommonAddress")
However, upon creation of user, I was unable to retrieve Address at all as it is still null. Is there a way to resolve this issue?

Pass your address model to the partial just like
#Html.Partial("CommonAddress", Model.Address)
If you do not have a model yet, pass a default/empty model from your Controller Edit action (the one that handles the GET HTTP request) to the view.

Related

ASP.NET MVC Tuple

In my View i have to put two different Forms and i have to use two different ViewModels. So i decided to use Tuple.
View:
#model Tuple<pi.Models.AddNewMechanic,pi.Models.ExistingUser>
and I got two forms
But how can i recive it from View in HttpPost Controler?
I tried like that:
public ActionResult AddMechanic(Tuple<pi.Models.AddNewMechanic, pi.Models.ExistingUser> model) {}
but i got message it cannot find method with parameter, so how I have to implement it inside this method, but there is a question how?
I strongelly sugest you create a new Model and inside of your new model, you can put this two object. Take care to dont mix domain model and view model. Otherwise, you will have always this kind of problem.
Domain Model
- class a
- class b
View Model
- class AB
prop A, prop B
I suggest you do this by the book, which would be:
AddMechanic.cshtml has no special view model, but contains two partial views. This is your "page with two forms".
_AddNewMechanic.cshtml is the first partial view form, which has AddNewMechanic as view model.
_ExistingUser.cshtml is the second partial view form, which has ExistingUser as view model.
The form in _AddNewMechanic.cshtml posts to the AddNewMechanic action method, which takes an AddNewMechanic as parameter.
The form in _ExistingUser.cshtml posts to the AddExistingMechanic action method, which takes an ExistingUser as parameter.
Upsides:
No need for any Tuple weirdness.
You can keep your existing View Models.
Your action method parameters will not normally be null, so no need for weird null checks.
Easy to follow and understand your code.

Some clarity on how to use View Models with MVC and ModelBinding please

I am getting confused about the use of ViewModels in an edit form where one of the properties is the editable entity ie
ViewModel
Entity
Actions
The model desclaration at the top of the View page:
#model MyProject.Models.ViewModel
Not
#model MyProject.Models.Entity
So what is the best way to represent the Entity Property which is the one that needs updating. I first started making a variable out of it.
Entity myEntity = ViewModel.Entity;
So each form element edit field might be represented by:
#Html.EditorFor(model => myEntity.Name)
However what happens with the Model Binding parameters in the post action?
[HttpPost]
public ActionResult Edit(Entity myEntity)
db.Entities.Attach(myEntity);
db.ObjectStateManager.ChangeObjectState(myEntity, EntityState.Modified);
db.SaveChanges();
So this question is really about how to deal with editable property objects in a ViewModel as opposed to a specific Entity Object that could be passed in as the Model which is straight forward.
Answer most likely simple.
Huge thanks in advance.
EDIT:
Feedback on how to reference domain objects from a ViewModel in a View. I have found that if I reference them directly in the lambda expresions, then model binding works fine as it can use the derived ids to navigate around the returned ViewModel. If one use a local variable in the View then this variable name is then used in the Id which then breaks the ViewModel Model binding mapping.
Your POST action should take the view model as parameter, not the domain model:
[HttpPost]
public ActionResult Edit(ViewModel viewModel)
then you should use the ID of this viewModel to retrieve the corresponding domain model from the database that needs to be updated. And then update the properties of this domain model from the view model. Finally persist the domain model back to the database.

need i create one model for each view in MVC4

Actually i am new learner for MVC4, my boss want to change the old asp.net webform to MVC4.
that i have some problems.
one is for each view is that need to create seperate model?
for example, in login page, users just put their name and password and submit.
so in order to receive those name and password, need i create one model for that name and password, namely one auth class with two class member, name and pass.
Or is there any better way to transfer old one to MVC
What you're talking about is a View Model - a class that represents your view / form. Instance of this class will be passed as a parameter to your Login action and will contain username and password. You will usually name your view model class after the view, eg. LoginViewModel.
It is an accepted way to create MVC applications.

automapper, where do you put your code to map View Model to Entity

my mvc3 project has following layers.
controller -> service -> repository.
I need to map ViewModel to Entity, not sure which layer is the right one to put the code in.
I know its either controller or service, please let me know which one I should use, and if you could please let me know why.
thank you.
I need to map ViewModel to Entity, not sure which layer is the right one to put the code in.
Controller of course. The service and repository layers don't know what a view model means. They manipulate only domain models.
So inside the controller you use the .Map<TSource, TDest> call to do the mapping back and forth between a domain model and a view models. But the mapping definition itself (.CreateMap<TSource, TDest> call) is done once per AppDomain lifetime, ideally in a Profile.
So let's consider a couple of typical workflows within a controller action in RESTful terms
GET (SELECT in RDBMS terms):
controller queries the service layer to retrieve a domain model (an aggregate root in most situations)
controller calls the mapping layer to map the domain model to a view model
controller passes the view model to the view
PUT (INSERT in RDBMS terms):
controller receives a view model from the view as action argument
controller maps the view model to a domain model
controller passes the domain model to the service layer for processing
controller redirects to a GET action
DELETE (DELETE in RDBMS terms)
controller receives an id as action parameter
controller passes the id to the service layer for processing (delete)
controller redirects to a GET action
POST (UPDATE in RDBMS terms):
controller receives a view model from the view as action argument
controller queries the service layer to obtain a domain model that we want to update using the unique Id contained in the view model
controller updates only the properties of the domain model that was retrieved that are also present in the view model. For example the domain model might consist of a Username and IsAdmin properties and the view model will obviously consist only of a Username property. So we leave the IsAdmin property on the domain model untouched and update the Username property. In AutoMapper terms this translates to the following void overload of the .Map<TSource, TDest> method: Mapper.Map<ADomain, ViewModel>(domainInstanceControllerRetrievedUsingTheId, viewModelInstancePassedAsArgument);
controller passes the updated domain model to the service layer for processing (update)
controller redirects to a GET action
Armed with those 4 workflows you are ready for the CRUD world.
P.S. A REST reminder:
Create = PUT
Retrieve = GET
Update = POST
Delete = DELETE

ASP.NET MVC model defaults on post

I have an ASP.NET MVC App, where I have interfaces for each viewmodel.
On a view called /Product/Details/50 I can edit details for product with id = 50.
I use strongly typed views, with the type being IProduct. I use Castle Windsor to do DI. When I post the edit form on the /Product/Details/50 view, the IProduct instance defaults to what it was set to on the HttpGet method called Details(int id) in the same controller.
I guess it's something to do with modelbinding. If I change the HttpPost method Details(IProduct product) to Details(Product product) it seems to work fine.
Any ideas?
The issue here is that when we encounter IProduct, we don't know which type to instantiate. Our model binders don't integrate with your DI container. For the most part, I agree with Charlino, your domain models should probably be interface based, but the objects you model bind to ought to be dumb simple POCO objects which represent the values posted in the form.

Resources