如何在asp.net MVC 3中实现复杂模型的“编辑”方法

时间:2012-12-24 21:07:28

标签: asp.net asp.net-mvc asp.net-mvc-3

在我的mvc 3网上商店应用程序中,我有这个模型:项目,产品,运输,用户表,其中1个项目包含1个产品,1个用户和1个运输。我需要以某种方式创建和编辑项目。创建时没有太多问题,因为我可以将“字段填充”作为参数传递给Crete(Post)方法。编辑有一个问题 - 出现Null Reference Exception。这是我的代码:
(控制器):
我将模型(类型为Item)传递给Edit Post方法作为参数并获得产品和运输,我希望,我充满了价值。

    [HttpGet]
    public ViewResult Edit(int itemId)
    {
        Item target = _itemsRepository.GetItem(itemId);

        return View(target);
    }

    [HttpPost]
    public ActionResult Edit(Item model)
    {
        Product p = model.Product;
        Shipping s = model.Shipping;

        // here goes some validation stuff

        if (ModelState.IsValid)
        {
            _productRepository.UpdateProduct(p);
            _shippingRepository.UpdateShipping(s);
            return RedirectToAction("Content");
        }
        return View();
    }    

强类型视图(填写表单的地方):

@model WebStore.WebStoreModels.Item

@using (Html.BeginForm())
{
@Html.ValidationSummary(true)

<fieldset>
    <legend>Product</legend>
    @Html.HiddenFor(i => i.ItemId)

    <p>Name: </p>
    <p>
        @Html.EditorFor(i => i.Product.Name)
        @Html.ValidationMessageFor(i => i.Product.Name)
    </p>
   // and so on
</fieldset>

<fieldset>
    <legend>Shipping</legend>

    <p>Cost: </p>
    <p>
        @Html.EditorFor(i => i.Shipping.Cost)
        @Html.ValidationMessageFor(i => i.Shipping.Cost)
    </p>        
    // so on
</fieldset> 
<p>
    <input type="submit" value="Save"/>
</p>

}

当我填写表单并单击“安全”按钮时,UpdateProduct()方法中的ProductRepository类中出现NullReferenceException:

public class ProductRepository : IProductRepository
{
    private WebStoreDataContext _dataContext;

    public ProductRepository(WebStoreDataContext dataContext)
    {
        _dataContext = dataContext;
    }

    public Product GetProduct(int productId)
    {
        return _dataContext.Products.SingleOrDefault(p => p.ProductId == productId);
    }
    public void UpdateProduct(Product p)
    {
        var dbProduct = GetProduct(p.ProductId);
        dbProduct.Name = p.Name;   // here the exception occures
        dbProduct.Description = p.Description;
        dbProduct.Price = p.Price;
        dbProduct.Category = p.Category;
        dbProduct.SubCategory = p.SubCategory;
        _dataContext.SubmitChanges();
    }

好像我不能使用这个作业:

Product p = model.Product;

我也尝试过:(在视图中,然后将其分配给编辑(后)方法中的产品)

TempData["product"] = @Model.Product;  

并且:(视野中)

@Html.Hidden("product", @Model.Product)  

并将其作为参数传递给Edit(Post)方法:

[HttpGet]
public ViewResult Edit(Product p, Shipping s)  

我认为问题与模型有关 任何帮助都会很棒,很抱歉这么多代码)

1 个答案:

答案 0 :(得分:2)

您需要在视图中添加隐藏的ProductId输入:

@using (Html.BeginForm())
{
    @Html.HiddenFor(i => i.Product.ProductId)
    ...
}

您需要拥有此行的原因是,当您提交表单模型时,binder会查看每个输入(包括隐藏的输入),并将它们绑定到您传递的Item model的属性{{1}行动。之前,当您没有此行时,只会填充以下属性:

  • Item.ItemId
  • Item.Product.Name
  • Item.Shipping.Cost

您的模型没有Item.Product.ProductId值的信息。此属性为[HttpPost],这意味着在提交表单时它变为等于0。在你的int方法中,你试图通过Id获取产品,显然它找不到id = 0的产品,这就是为什么这个调用返回_productRepository.UpdateProduct(p);导致下一个空引用异常的原因线。