Reputation: 571
I am getting stuck using a ViewModel. Suppose I want to give a logged-in person an Edit Form with only a few of the fields from my Person domain model (maybe I want to custom annotate validations in the ViewModel).
I am getting stuck in two separate places in the controller (I have marked them with "<<< >>>").
When I pass the whole Person object as a property to my ViewModel, I know what to do. I can get my code to only update the name fields, but then I have lost my ability to validate the individual properties in my ViewModel. On the hand if I limit the properties in my ViewModel to only to a few properties, then my code in the GET section where I cann vm.Person doesn't work, since I am not passing the Person.
I scanned many examples on SO, but they were all using AutoMapper. Can I accomplish this without a mapper, and/or how do I write my own? And thanks in advance!
Model:
public class Person()
{
public int PersonId { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string Email { get; set; }
}
ViewModel:
public class LoggedInPersonViewModel()
{
public int PersonId { get; set; }
[Required(ErrorMessage = "Last Name is required")]
public string LastName { get; set; }
public string FirstName { get; set; }
}
Repository:
public Person GetLoggedInPerson()
{
var user = HttpContext.Current.User.Identity;
var userid = user.GetUserId();
return db.People.SingleOrDefault(i => i.UserId == userid);
}
Controller:
public class RegistrationController : Controller
{
//Get Logged in User, Edit Form
public ActionResult UpdateDetails()
{
LoggedInPersonViewModel vm = new LoggedInPersonViewModel();
<<<Do I also need a Person property in my ViewModel>>>
vm.Person = repository.GetLoggedInPerson();
return View(vm);
}
//POST
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UpdateDetails(LoggedInPersonViewModel loggedinpersonviewmodel)
{
if (ModelState.IsValid)
{
<<<what do i do here? is this correct? Again I cannot use Person if not in my VM.>>>
//Person person = db.People.Find(loggedinpersonviewmodel.PersonId);
//Person.FirstName = loggedinpersonviewmodel.FirstName;
//Person.LastName = loggedinpersonviewmodel.LastName;
//db.Entry(person).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index", "Person");
}
return View(loggedinpersonviewmodel);
}
}
}
Is there a way...or do I have to use AutoMapper for this?
Upvotes: 4
Views: 1102
Reputation: 133403
I think you need to Map LoggedInPersonViewModel
and Person
. Example
public ActionResult UpdateDetails()
{
var person = repository.GetLoggedInPerson();
LoggedInPersonViewModel vm = new LoggedInPersonViewModel();
vm.PersonId = person.PersonId;
//Rest of properties
...
//return view model
return View(vm);
}
I would recommend AutoMapper this type of work. i.e. AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another.
Upvotes: 4