2017-08-02 87 views
0

有许多解决方案如何将模型映射到mvc asp.net中的视图模型,如automapper或valueinjecter。但是,我无法弄清楚如何映射回来。一个简单的例子如何将ViewModel映射到Model(MVC EF)

我有一个复杂模型像这样一个在这里

public class Address 
{ 
    public int AddressID { get; set; } 

    public string OwnerID { get; set; } 
    public virtual ApplicationUser Owner { get; set; } 

    public String Name { get; set; } 

    public String Street { get; set; } 

    public int ZipCode { get; set; } 

    public String City { get; set; } 

    public string Email { get; set; } 

    // fancy business logic stuff like 
    public Nullable<Guid> requestCode { get; set; } 

    // or even this 
    public string BestFriendID { get; set; } 
    public virtual ApplicationUser BestFriend{ get; set; } 

    public virtual ICollection<OtherModel> Mycollection { get; set; } 

    // And some enums 
    public MyEnum MyEnum { get; set; } 
} 

但随后在一个场景中,我只是想编辑的名称和该地址的电子邮件,让我去进取,创造视图模型为它

public class SimpleEmailEditVM 
{ 
     [MyDataAnnotations] 
     public String Name { get; set; } 

     [MyDataAnnotations] 
     public String Email { get; set; } 
} 

这可以建立非常简单的看法是这样的一个

@model project.ViewModels.SimpleEmailEditVM 
@Html.EditorFor(model => model, new { htmlAttributes = new { @class = "form-control" } }) 

我可以添加视图模型,例如Street作为一个字段,不需要更新视图。用模型可以很容易地完成从模型到视图模型的映射。 valueinjecter,但现在我的问题:我如何映射回来?

在视图模型中没有ID信息,所以我如何找到正确的模型(我可以想象,多个条目具有相同的名称和电子邮件,但完全不同的ID)?那控制器是怎么样的?

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit([Bind] SimpleEmailEditVM vm) 
    { 
     if (ModelState.IsValid) 
     { 
      /* find the correct address from db and update the 
       fields specified in the viewmodel? */ 
      db.Entry(address).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(address); 
    } 

我能想到的一个解决方案是添加Id并将其隐藏(like this here)。这是正确的和唯一的方法吗?这里的问题是,我的身份证已通过,我可以想象,将内部身份证的传递给用户并不是很好的做法。

回答

0

您可以使用temproray会话(TempData)将值从另一个操作发送到操作。

请检查enter link description here

+0

in view action TempData [“TempId”] = id; 用于后续操作var id = TempData [“TempId”]; – pisi1001

1

我能想象这是不通过内部ID对 的用户来说是非常好的做法。

暴露身份证本身并不是一个问题,除非该身份证是像SSN这样的敏感数据。此问题的ID在网址中显示。您的用户ID显示在您的个人资料中。

诀窍是确保当id回来时,检查其有效性并检查执行该操作的标识是否被允许执行该操作。这可能是角色或权限检查,或者可能需要在记录级别进行细化。

这里有一些伪码演示这个。

[HttpPost] 
[ValidateAntiForgeryToken] 
public ActionResult Edit([Bind] SimpleEmailEditVM vm) 
{ 
    var itemToEdit = db.Find(vm.Id); 

    //Make sure Id is valid 
    if(itemToEdit == null) return BadRequest(); 

    //Make sure user can edit this object 
    if(!User.IsInRole("CanEditItems")) return Forbidden(); 
    if(itemToEdit.AllowedUser != User.Identity.Name) return Forbidden(); 

    if (ModelState.IsValid) 
    { 
     /* find the correct address from db and update the 
      fields specified in the viewmodel? */ 
     db.Entry(address).State = EntityState.Modified; 
     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    return View(address); 
}