在ASP.NET MVC中编辑View Model的一些属性

时间:2015-07-25 12:53:44

标签: asp.net-mvc entity-framework

我正在使用实体框架数据库优先方法。我们假设我有一个名为Product的模型类,该类具有NumberOfViews属性。在编辑页面中,我将product 的实例传递给控制器

问题是我无法在编辑页面中添加@Html.EditorFor(model => model.NumberOfViews),因为它假设NumberOfViews每次访问时都会更新@Html.HiddenFor(model => model.NumberOfViews)产品页面,网站管理员

我无法将其添加为Product.NumberOfViews = db.Products.Find(Product.Id).NumberOfViews;,因为如果管理员检查了元素,他可以手动编辑它。

此外,如果我尝试以编程方式在服务器端设置值(例如null),则会出现以下错误:

  

ObjectStateManager中已存在具有相同键的对象。 ObjectStateManager无法使用相同的键跟踪多个对象。

如果我不将其添加到视图或控制器中,则值为def __get__(self, instance, owner=None): ,从而覆盖之前的任何值。

那我该怎么办?

1 个答案:

答案 0 :(得分:1)

我注意到很多人为他们的实体框架使用与他们的MVC控制器相同的模型。我一般不鼓励这种做法。在我看来,数据库模型与视图模型不同。

有时,视图所需的信息少于数据库模型提供的信息。例如,在修改帐户密码时,视图不需要名字,姓氏或电子邮件地址,即使它们可能都位于同一个表中。

有时它需要来自多个数据库表的信息。例如,如果用户可以为其简档存储无限数量的电话号码,则用户信息将在用户表中,然后联系信息与联系表中的联系信息。但是,在修改用户配置文件时,他们可能希望添加/编辑/删除其中一个或多个数字,因此视图需要所有数字以及名字,姓氏和电子邮件地址。

这就是我要做的事情:

// This is your Entity Framework Model class
[Table("Product")]
public class Product 
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ProductId { get; set; }

    public string Name { get; set; }

    public int NumberOfPageViews { get; set; }
}

// This is the model you will use in your Edit action.
public class EditProductViewModel
{
    public int ProductId { get; set; }

    public string Name { get; set; }
}

public class ProductController : Controller
{
    IProductService service;

    //...

    [HttpGet]
    public ActionResult Edit(int productId)
    {
        var product = service.GetProduct(productId);
        var model = new EditProductViewModel() 
        {
            ProductId = product.ProductId,
            Name = product.Name
        };
        return View(model);
    }

    [HttpPost]
    public ActionResult Edit(EditProductViewModel model)
    {
        if (ModelState.IsValid)
        {
            var product = service.GetProduct(model.ProductId);
            product.Name = model.Name;
            service.Update(product);
        }

        // ... 
    }
}