在MVC中的ViewModel中仅使用Model中的一些属性

时间:2014-01-15 20:38:19

标签: c# asp.net-mvc

我使用ViewModel陷入困境。假设我想给登录的人一个编辑表单,其中只包含我的Person域模型中的一些字段(也许我想在ViewModel中自定义注释验证)。

我被困在控制器中的两个不同位置(我用“<<<>>>”标记了它们)。

当我将整个Person对象作为属性传递给我的ViewModel时,我知道该怎么做。我可以让我的代码只更新名称字段,但后来我失去了验证ViewModel中各个属性的能力。如果我将ViewModel中的属性限制为仅限于几个属性,那么我在GET部分中我的代码vm.Person的代码不起作用,因为我没有传递Person。

我在SO上扫描了很多例子,但他们都使用了AutoMapper。我可以在没有映射器的情况下完成此操作,和/或如何编写自己的映射器?并提前感谢!

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);
    }
}

}

有没有办法......或者我必须使用AutoMapper吗?

1 个答案:

答案 0 :(得分:4)

我认为您需要映射LoggedInPersonViewModelPerson。实施例

public ActionResult UpdateDetails()
{
    var person = repository.GetLoggedInPerson();
    LoggedInPersonViewModel vm = new LoggedInPersonViewModel();

    vm.PersonId = person.PersonId;
    //Rest of properties
    ...

    //return view model
    return View(vm);
}

我建议AutoMapper这类工作。即AutoMapper是一个简单的小型库,用于解决一个看似复杂的问题 - 摆脱将一个对象映射到另一个对象的代码。