是什么导致模型绑定在ASP.NET MVC 1.0中失败?

时间:2010-02-01 04:30:16

标签: asp.net-mvc

这是我的课......任何指针?

public class Cart
{
    private List<CartLine> lines = new List<CartLine>();
    public IList<CartLine> Lines { get { return lines.AsReadOnly(); } }

    public void AddItem(Product product, int quantity)
    {
        var line = lines.FirstOrDefault(l => l.Product.ProductID == product.ProductID);

        if (line == null)
            lines.Add(new CartLine { Product = product, Quantity = quantity });
        else
            line.Quantity += quantity;

    }

    public decimal ComputeTotalValue() 
    {
        return lines.Sum(l => l.Product.Price * l.Quantity);
    }

    public void Clear() 
    {
        lines.Clear();
    }

    public void RemoveLine(Product product)
    {
        lines.RemoveAll(l => l.Product.ProductID == product.ProductID);
    }
}

public class CartLine
{
    public Product Product { get; set;}
    public int Quantity { get; set;}
}

在控制器中添加Action方法。

public RedirectToRouteResult AddToCart(Cart cart, int productID, string returnUrl)
        {
            Product product = productsRepository.Products.FirstOrDefault(p => p.ProductID == productID);
            cart.AddItem(product, 1);
            return RedirectToAction("Index", new { returnUrl });
        }

        public RedirectToRouteResult RemoveFromCart(Cart cart, int productID, string returnUrl)
        {
            Product product = productsRepository.Products.FirstOrDefault(p => p.ProductID == productID);
            cart.RemoveLine(product);
            return RedirectToAction("Index", new { returnUrl });
        }

        public ViewResult Index(Cart cart, string returnUrl)
        {
            ViewData["returnUrl"] = returnUrl;
            ViewData["CurrentCategory"] = "Cart";
            return View(cart);
        }

我的自定义模型绑定器:

public class CartModelBinder : IModelBinder
    {
        private const string cartSessionKey = "_cart";

        #region IModelBinder Members

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (bindingContext.Model != null)
                throw new InvalidOperationException("Cannot update instances");
            Cart cart = (Cart)controllerContext.HttpContext.Session[cartSessionKey];
            if (cart == null)
            {
                cart = new Cart();
                controllerContext.HttpContext.Session["cartSessionKey"] = cart;
            }
            return cart;
        }
        #endregion
    }

3 个答案:

答案 0 :(得分:0)

在没有看到控制器操作方法的情况下,我能看到的第一件事是您没有可以写入的属性,因此假设此对象是只读模型。至少,我们需要查看使用此对象的控制器操作方法,以及视图(如果有)。

<强>更新

据我了解,ModelBinder的目的是获取从HTML表单,查询字符串和/或会话数据接收的数据并填充.NET类的实例,相反,从中提供数据用于HTML表单的类实例。从我所看到的,您的Cart类具有行为和存储,但没有读/写属性形式的可传输数据。 MVC使用.NET反射来查找类中的读/写属性。由于您的类中没有读/写属性,因此您的模型绑定失败,因为您的自定义ModelBinder无需传输。

您可能希望查看这两篇文章以获取模型绑定帮助:

http://odetocode.com/Blogs/scott/archive/2009/04/27/6-tips-for-asp-net-mvc-model-binding.aspx

http://odetocode.com/Blogs/scott/archive/2009/05/05/iterating-on-an-asp-net-mvc-model-binder.aspx

答案 1 :(得分:0)

如果覆盖模型绑定器,则负责从表单发布中填充对象。在您显示的自定义模型绑定器中,您实际上并未设置Cart的属性。您需要设置其属性。

答案 2 :(得分:0)

感谢所有回复,但我想出了问题。这是一个非常愚蠢的事情,由ali@asp.net论坛指出

问题在于行controllerContext.HttpContext.Session [“cartSessionKey”] = cart;

它应该只是controllerContext.HttpContext.Session [cartSessionKey] = cart;

我仍然无法相信我以前没有抓过这个。