MVC对象更改跟踪

时间:2013-01-08 13:01:37

标签: c# .net asp.net-mvc entity-framework

我目前遇到一个问题,我需要在编辑字段中查看哪些字段已更改以供审核,我有代码,但我认为我的问题在于我的MVC视图。

我有(测试代码):

[HttpPost]
public ActionResult Adjustment(GroupPolicy groupPolicy)
{
          if (ModelState.IsValid)
          {
              _service.SaveGroupPolicy(groupPolicy);
              return RedirectToAction("Index");
          }
          return View(groupPolicy);
}

哪个好,政策保存。但是,请考虑到这一点:

GroupPolicy有3个字段(实际上有60个字段):

bool IsPolicy
string Name
string Description

名称和描述在表格上,所以没关系。表单上未使用IsPolicy,因此在调整方法中回发到GroupPolicy对象时会将默认为false

我无法将IsPolicy放在表单上的隐藏字段中,因为在我的实际解决方案中,对于60多个字段来说这不会很优雅,HTML将遍布整个地方。

现在bool默认为false,它完全取消了我知道该字段是否已经改变的机会。我真正想要的是保存这些数据的方法,同时在Edit表单上保留新信息。

这可能吗,我错过了一些明显的东西吗?

2 个答案:

答案 0 :(得分:2)

首先,GroupPolicy应该是视图模型,而不是实体 - 因此应该为视图量身定制,例如。

public class GroupPolicyViewModel
{
    [HiddenInput]
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    ...
}

然后在您的操作中,您无需担心分配已更改的值,您只需将视图模型直接映射到例如。

public ActionList Adjustment(GroupPolicyViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        // pull actual entity from service
        var groupPolicy = _service.GetGroupPolicy(viewModel.Id);
        // update entity from view model
        groupPolicy.Name = viewModel.Name;
        groupPolicy.Description = viewModel.Description;
        ...
    }
}

这使您的视图和视图之间保持清晰的分离。商业逻辑。此外,它允许您为客户端验证添加注释,而不会影响您的真实模型。

  

GroupPolicy有3个字段(实际上有60个字段)

我建议使用AutoMapper来解决这个问题。

// call this once only e.g. Application_Start in the Global.asax
Mapper.CreateMap<GroupPolicyViewModel, GroupPolicy>();
...
// in your Adjustment action
var groupPolicy = _service.GetGroupPolicy(viewModel.Id);
groupPolicy = Mapper.Map<GroupPolicyViewModel, GroupPolicy>(viewModel, groupPolicy);
_service.SaveGroupPolicy(groupPolicy);

答案 1 :(得分:1)

如果IsPolicy不在表单上,​​那么它甚至不应该是您的模型的一部分 - 这将阻止将此字段发布到您的模型中,因此IsPolicy甚至不需要您的检查。

不是将GroupPolicy作为参数接受到操作中,而是创建一个仅包含表单上字段的缩减对象GroupPolicyInputModel

然后使用您的通用审核仅比较所有发布的字段,按照任何其他形式。