有很多解决方案如何将模型映射到mvc asp.net中的viewmodel,如automapper或valueinjecter。但是,我无法弄清楚如何映射回来。一个简单的例子
我有一个像这样的复杂模型
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; }
}
但是在一个场景中,我只想编辑这个地址的名称和电子邮件,所以我继续为它创建一个viewmodel
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" } })
我可以在viewmodel中添加例如Street
作为字段,不需要更新视图。从模型到视图模型的映射可以用例如模型轻松完成。 valueinjecter,但现在我的问题:我如何映射回来?
在viewmodel中没有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 :(得分:1)
我可以想象,将内部ID传递给不是很好的做法 用户。
除非id是敏感数据(如SSN),否则公开id本身并不是问题。此问题的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);
}
答案 1 :(得分:0)
您可以使用temproray会话(TempData)将值发送到另一个操作的操作。