Mvc: Alternative for form collection to better handle huge amount of parameters - asp.net-mvc-3

I have a form that has just 3 fields and I am writing this
to a database by passing the values using a form collection to
the business layer.
Assuming I have 35 fields on my form and wants to write this
to the database. Is there a better way of doing this than
listing 35 fields in my code. I want to reduce the amount of code
I write.
[HttpPost]
Public ActionResult Create(FormCollection objFrmCollect)
{
Employee employee = new Employee();
employee.Name = objFrmCollect["Name"];
employee.Gender = objFrmCollect["Gender"];
employee.City = objFrmCollect["City"];
EmployeeBusinessLayer empBus = new EmployeeBusinessLayer();
empBus.AddEmployee(employee);
return RedirectToAction("Index");
}

You should use Model Binder like this:
public ActionResult Create(Employee employee)
It will automatically populate employee model with posted values.
Here is more information about model binding:
http://www.codeproject.com/Articles/710776/Introduction-to-ASP-NET-MVC-Model-Binding-An-Absol

Automatic conversion of form collection to a model class can't be direct. So the best way you should use is from the view where you are fetching the form collection, you should use directly model properties. i.e. you should bind it to a model.
So the alternative for form collection to handle huge amount of parameters is binding it to model

Related

.NET MVC3/Holding temp model

I have a situation where i have to take input(form) from user. After continue button is pressed next view page is displayed. But after continue is pressed i don't want to store the model in the DB. I have to display some details(combining some tables) according to input given by the user earlier and again get some data from user. Only then i want to store the model in the respective tables.
How can i perform this? I tried getting Model from user and passing to the function that generates next page. Is this is way to do it? or there is other way around?
Store the model submitted by the first form in session.
[HttpPost]
public ActionResult ContinueForm1(Model1 model1)
{
if(ModelState.IsValid)
{
Session["Model1"] = model1;
return View("Form2");
}
return View();
}
[HttpPost]
public ActionResult ContinueForm2(Model2 model2)
{
if(ModelState.IsValid)
{
... model2 is already here, get the model1 from session
... and save to datatbase finally return a different view or redirect to some
... other action
}
return View();
}
You are heading down the right track.
You need to grab the model that is passed back from the first view - preferably you are using ViewModels here rather than binding directly to your db models. Have a look at http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/ and Why should I use view models? as to why these are good things.
The easiest way to do this is to pass the model in as an argument to your method e.g.
Assuming that your views are using the same ViewModel ( which may or may not be true) then you can send the viewmodel straight to your new view - else you can copy the elements into a new viewModel and send that.
e.g.
[HttpPost]
public ViewResult Step1(MyViewModel viewModel)
{
//Do some validation here perhaps
MySecondViewModel secondViewModel = new MySecondViewModel{
Id = viewModel.Id,
// etc. etc.
};
return View("Step2", secondViewModel);
}
Then you can carry on as you need until you have to persist the entity to the database.
NB as you do not need to do anything special in the form to make it post the model as an argument as long as the view is strongly typed to that ViewModel.

Querying database when using viewmodel on web application asp.net mvc3

I have a problem with viewmodel, when I try to add new enregistrement to my database when I have view titly typed with my viewmodel I get DbEntityValidationErrors.
This is code using viewmodel :
[HttpPost]
public ActionResult Create(Annonce annonce)
{
/*
if (ModelState.IsValid)
{
*/
_userservice.addannonce(annonce);
return RedirectToAction("Index");
/*
}
return View(new AnnonceView(annonce));
* */
}
But when I use my entity domain Annonce directly on view, there is any problem. Help me please and sorry for my bad english
I am assuimng your addannounce method is expecting an object of your EntityModel type. Not Viewmodel. ViewModel is specific to handle the View. It is not same as your Entity Model. You can not send a View Model which you created as it is to the entity framework to save it. You need to send an Entity Model. So probably you can read the values of ViewModel and set as the relevant property values of Entity Model and send that to be saved. Something like this
YoueEntity.Announce objEntityAnnounce=new YoueEntity.Announce();
//Read from the posted viewmodel and set the values to entity model.
objEntityAnnounce.ID=annonce.ID;
objEntityAnnounce.Title=annonce.Title;
//Other relevant Properties as well
_userservice.addannonce(objEntityAnnounce);
There are libraries like AutoMapper which does this mapping, You may take a look at them,

which is the best practices for exposing entity or DTO to view in mvc3?

I have created my own customized lots of architecture including n-tier layers for different different technology.
Currently working on n-tier architecture with asp.net mvc framework. The problem is I have entity framework at data access layer. As the entities will have all it's relational metadata and navigation properties, it becomes heavier one. I am feeling like it is not wise to expose this entities directly over mvc view.
I am more favor in exposing own customized model of entities over mvc view which one be lighter one.
But this also leads me overhead of converting data from my original entities to customized model.
For example I have Employee entity which is as generated from edmx file of entity framework. It contains total 20 fields with all navigation properties.
Now over view in mvc I need to show only 2 fields for edit.
So do we need to expose original entity to view or need to create DTO/customized model of that two field and than expose that view?
I would use a view model. I have learnt not to expose my domain objects to the view, I rather map my domain object to the view model and return this view model to the view.
Here is a partial view model, you might have more properties if you need more employee data to create/edit or display:
public class EmployeeViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
In my action method of my controller it would look something like this:
public ActionResult Edit(int id)
{
Employee employee = employeeRepository.GetById(id);
// Mapping can be done here by using something like Auto Mapper, but I am
// manually mapping it here for display purposes
EmployeeViewModel viewModel = new EmployeeViewModel();
viewModel.FirstName = employee.FirstName;
viewModel.LastName = employee.LastName;
return View(viewModel);
}
And then your view might look something like this:
<td>First Name:</td>
<td>#Html.TextBoxFor(x => x.FirstName, new { maxlength = "15" })
#Html.ValidationMessageFor(x => x.FirstName)
</td>
I prefer to have a view model that has only the values of employee that is needed on the view. Let say your employee has 20 properties, and you only need to update 2 fields, why then pass all 20 to the view? Use only what you need.
You can expose original entity, that is nothing bad. But as soon as you need some other information on the view e.g. instead of Name and Lastname you need FullName, then you should create an EmployeeViewModel with only needed properties. You initialize it with desired values in an action and then pass it to the view.

How can i supply value to Textbox generate from #Html.EditorFor in MVC razor?

I am just new to MVC.
when we use "#Html.EditorFor" in razor view, it generates textbox.
My requirement is that I need to supply some value from viewbag or session to user's in that textbox?
Is it possible and if yes how can i do?
OR
What are the alternatives?
In your action method in the controller, pre-load a model with some data:
public ActionResult Index()
{
MyModel model = new MyModel();
model.FirstName = "Bob";
model.LastName = "Hoskins";
return View(model);
}
Then make your View strongly typed. These pre-set values should now appear on your view. You probably want to populate them from a service layer or resource file, rather than have them as hardcoded strings like my example.

asp.net mvc 2 multiple selection listbox. how to read values in controller

I'm having a hard time getting a fairly simple binding to work.
When editing an employee I want to display a listbox containing all the available roles in the system, (the employee's roles selected), and when saving the employee I want the selected roles to get populated by MVC into the Employee object which comes as an input param to the controller.
I know I can read the comma-separated values from Request.Form, but I'd rather not touch the Request object directly in my controllers as this makes them harder to test.
What is the best way to get MVC to supply me with the list of roles as an input param?
You have two options. The first is to get the values in the controller and put them into the ViewData dictionary, like so:
var list = EmployeeRoles.GetAll();
ViewData["EmployeeRoles"] = list;
Then you access it in the View using:
<%= (List<EmployeeRoles>)ViewData["EmployeeRoles"] %>
This way is kind of ugly because the view then has to know that it can use a 'magic string' to get an object out of the ViewData dictionary, which then has to be casted back into its original type.
The second way is more elegant, but introduces a little more complexity into your code. You create a ViewModel class, or basically a class that encapsulates all the data you want:
public class EmployeeViewModel
{
public Employee Employee { get; set; }
public ICollection<EmployeeRoles> EmployeeRoles { get; set; }
public EmployeeViewModel(Employee employee, ICollection<EmployeeRoles> roles)
{
Employee = employee;
EmployeeRoles = roles;
}
}
Then you would pass it from the controller to the view like so:
return View(new EmployeeViewModel (employee, roles);
On the view side, you'd access it like any other model:
<%= Model.Employee.Name %>
<%= Model.EmployeeRoles.First() %>
This method is more testable, but then you'd have to make a new ViewModel class for anything that requires data from more than one source.
As for returning the data from the view to the controller, the default model binder is actually quite good. You just have to use a HtmlHelper on the View to let it know what it should send the value back as. I don't have my book in front of me right now, but it should be something like this for a textbox:
<% Html.TextBox("Name", Model.Employee.Name) %>
The HtmlHelper will figure out what it needs to send back in order for the model binder to bind it correctly. I don't know what it is for a DropDownBox off the top of my head though.

Resources