Не удалось привязать модель к отправленным значениям формы для моего пользовательского типа .net (корзина), который хранится в сеансе - PullRequest
0 голосов
/ 08 июня 2011

При отправке формы в представлении ниже объект корзины в сеансе не удается обновить с введенными значениями на стороне клиента. Я что-то пропустил ? Виновата ли пользовательская модель?

Все имена элементов 1: 1 с именами и структурой свойств объекта корзины.

Просмотр отрывка:

         <% using (Html.BeginForm("UpdateCart", "Cart"))
       { %>



<% int index = 0; %>

<% foreach (var line in Model.Cart.Lines)
   { %>
<tr>
<%: Html.Hidden("Lines.Index", index) %>
<td align="center"><%: Html.TextBox("Lines[" + index + "].Quantity", line.Quantity)%></td>
<td align="left"><%: line.Product.Name%></td>
<td align="right"><%: line.Product.ListPrice.ToString("c")%></td>
<td align="right">
<%: (line.Quantity * line.Product.ListPrice).ToString("c")%>
</td>
</tr>

<%--<%: Html.Hidden("Lines[" + index + "].Product.ProductID", line.Product.ProductID)%>--%>

<% index++; %>

<% } %>

    <%: Html.Hidden("returnUrl", Model.ReturnUrl) %>


    <input type="submit" value="Update Cart" />

    <% } %>

Корзина Объект:

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

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

        public int Quantity
        { get; set; }
    }

Действие Метод, который получает отправленные данные формы и должен обновить объект корзины, связав значения формы:

[HttpPost]
    public RedirectToRouteResult UpdateCart(Cart cart, string returnUrl)
    {



         return RedirectToAction("Index", new { returnUrl });

    }

Пользовательская привязка модели, которая создает экземпляр корзины в сеансе и возвращает этот экземпляр для всех используемых контроллеров и методов.

public class CartModelBinder : DefaultModelBinder
{



    private const string cartSessionKey = "_cart";

    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        controllerContext.HttpContext.Session[cartSessionKey] = (Cart)bindingContext.Model;
    }




        public override 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;

        }
    }

1 Ответ

0 голосов
/ 08 июня 2011

Созданное вами связующее модель cutom вызывается при публикации ваших данных на сервере, поэтому ваша корзина параметров действия UpdateCart будет загружена данными из клиента, использующего связующее модель.Чтобы использовать пользовательский связыватель моделей для обновления сеанса после загрузки объекта, вы можете сделать это:

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

    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        controllerContext.HttpContext.Session[cartSessionKey] = bindingContext.Model;
    }
}

В этом связывателе моделей мы наследуем defaultmodelbinder и перебрасываем событие OnModelUpdate, которое происходит после связывания модели, поэтомув OnModelUpdated у нас есть модель со значениями из представления, и мы можем установить сеанс.

Но для DefaultModelBinder сделать привязку, вам придется изменить представление, имена входов должны соответствоватьимена свойств вашего объекта, поэтому вместо cart.Lines ["+ index +"] .Quantity следует использовать Lines ["+ index +"] .Quantity (сделать то же самое для других свойств).В вашем объекте Cart вы должны будете создать установщик для свойства Lines, потому что без этого связыватель по умолчанию не сможет установить введенное значение.Вам не нужно вызывать UpdateModel внутри вашего представления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...