我知道这个帖子有点老了,但我想我会重新发布它以获取我对此问题的解决方案的反馈。
我处于类似的情况,我的对象被传递给视图,而视图可能只显示该对象的一部分以进行编辑。显然,当控制器从默认模型绑定器接收到模型时,未回发的值变为空。保存这意味着数据库值变为空,只是因为它没有从视图中显示/返回。
我不喜欢为每个视图创建模型的想法。我知道这可能是正确的方式...但我一直在寻找一种可以相当快速地实现的可重用模式。
请参阅“MergeWith”方法...因为这将用于从数据库中获取对象的副本并将其与从视图返回的对象合并(回发)
namespace SIP.Models
{
[Table("agents")]
public class Agent
{
[Key]
public int id { get; set; }
[Searchable]
[DisplayName("Name")]
[Column("name")]
[Required]
[StringLength(50, MinimumLength = 4)]
public string AgentName { get; set; }
[Searchable]
[DisplayName("Address")]
[Column("address")]
[DataType(DataType.MultilineText)]
public string Address { get; set; }
[DisplayName("Region")]
[Searchable]
[Column("region")]
[StringLength(50, MinimumLength = 3)]
public string Region { get; set; }
[DisplayName("Phone")]
[Column("phone")]
[StringLength(50, MinimumLength = 4)]
public string Phone { get; set; }
[DisplayName("Fax")]
[Column("fax")]
[StringLength(50, MinimumLength = 4)]
public string Fax { get; set; }
[DisplayName("Email")]
[RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")]
[Column("email")]
[StringLength(50, MinimumLength = 4)]
public string Email { get; set; }
[DisplayName("Notes")]
[Column("notes")]
[DataType(DataType.MultilineText)]
public string Notes{ get; set; }
[DisplayName("Active")]
[Column("active")]
public bool Active { get; set; }
public override string ToString()
{
return AgentName;
}
public bool MergeWith(Agent a, string[] fields)
{
try
{
foreach (PropertyInfo pi in this.GetType().GetProperties())
{
foreach (string f in fields)
{
if (pi.Name == f && pi.Name.ToLower() != "id")
{
var newVal = a.GetType().GetProperty(f).GetValue(a,null);
pi.SetValue(this, newVal, null);
}
}
}
}
catch (Exception ex)
{
return false;
//todo: Log output to file...
}
return true;
}
}
}
要在控制器中使用它......你会有类似的东西......
[HttpPost]
public ActionResult Edit(Agent agent)
{
if (ModelState.IsValid)
{
Agent ag = db.Agents.Where(a => a.id == agent.id).ToList<Agent>().First<Agent>();
ag.MergeWith(agent, Request.Params.AllKeys);
db.Entry(ag).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(agent);
}
这样,在回发期间,它从数据库中获取对象,并使用视图中的对象更新它......但只更新回发的值。所以如果你有一个像“地址”或没有出现在视图中的东西..在更新过程中它没有被触及。
到目前为止,我已经对此进行了测试,并且我为自己的目的工作,但我欢迎任何反馈,因为我很想看看其他人如何克服这种情况。这是第一个版本,我确信它可以通过扩展方法或其他方式更好地实现。但现在 MergeWith 可以复制/粘贴到每个模型对象。