代码之家  ›  专栏  ›  技术社区  ›  Srikar Doddi

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

  •  0
  • Srikar Doddi  · 技术社区  · 15 年前

    这是我的课……有什么建议吗?

    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;}
    }
    

    在控制器中添加操作方法。

    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 回复  |  直到 15 年前
        1
  •  0
  •   Neil T.    15 年前

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

    更新:

    据我所知,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

        2
  •  0
  •   Haacked    15 年前

    如果您覆盖模型绑定器,那么您将负责从表单发布填充对象。在显示的自定义模型活页夹中,实际上没有设置购物车的属性。您需要设置它的属性。

        3
  •  0
  •   Srikar Doddi    15 年前

    谢谢你的回复,但我发现了问题。这是ali@asp.net论坛指出的一件非常愚蠢的事情

    问题出在controllerContext.httpContext.session[“cartsessionkey”]=cart行中;

    它应该只是controllerContext.httpContext.session[cartsessionkey]=cart;

    我还是不敢相信我以前没抓到这个。