SKale
SKale

Reputation: 571

Using only a few properties from Model in my ViewModel in MVC

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

Answers (1)

Satpal
Satpal

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

Related Questions