Увеличение идентификатора в корзине покупок

1

Я новичок в ASP.NET MVC 5 (VS2013) и пытаюсь создать простую корзину покупок, где элементы можно добавлять и удалять.

Проблема, которую я имею, - это когда я нажимаю кнопку ADD, добавляемая строка не увеличивает идентификатор, как я ожидал. Он всегда возвращается как 0 (в HTML, который отображается в браузере), и, таким образом, кнопка удаления при нажатии удаляет все записи как следствие (все ID совпадают).

Я пытаюсь сделать это без AJAX и TempData/Session/ViewBag/ViewData, чтобы я мог лучше изучить привязку "автоматическая модель" (где размещенные значения привязаны к свойствам).

Контроллеры \ShoppingBasketController.cs

public class ShoppingBasketController : Controller
{
    public ActionResult Index()
    {
        ShoppingBasketViewModel vm = new ShoppingBasketViewModel();

        return View(vm);
    }

    [HttpPost]
    public ActionResult Index(ShoppingBasketViewModel vm, string ButtonClicked)
    {
        if (ButtonClicked.ToLower() == "add")
        {
            return AddShoppingBasketItem(vm);
        }
        else if (ButtonClicked.ToLower().Contains("remove_"))
        {
            return RemoveShoppingBasketItem(vm, ButtonClicked);
        }
        else
        {
            return View(vm);
        }
    }

    private ActionResult AddShoppingBasketItem(ShoppingBasketViewModel vm)
    {
        vm.Items.Add(new ShoppingBasketItemViewModel() { Id = vm.NextId, Name = String.Format("Name {0}", vm.NextId) });

        vm.NextId++;

        return View(vm);
    }

    private ActionResult RemoveShoppingBasketItem(ShoppingBasketViewModel vm, string WhichRemoveButtonClicked)
    {
        int idToDelete = 0;

        bool success = int.TryParse(WhichRemoveButtonClicked.Split('_').LastOrDefault(), out idToDelete);

        if (!success)
        {
            throw new ArgumentException("WhichRemoveButtonClicked", String.Format("Could not get Id to delete from the button clicked. '{0}", WhichRemoveButtonClicked));
        }

        vm.Items.RemoveAll(item => item.Id == idToDelete);

        return View(vm);
    }
}

Модели \ShoppingBasketViewModel.cs

public class ShoppingBasketViewModel
{
    public int NextId { get; set; }
    public List<ShoppingBasketItemViewModel> Items { get; set; }    

    public ShoppingBasketViewModel()
    {
        this.Items = new List<ShoppingBasketItemViewModel>();            
    }
}

Модели \ShoppingBasketItemViewModel.cs

public class ShoppingBasketItemViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

~/Views/Shared/DisplayTemplates/ShoppingBasketViewModel.cshtml

 @model ShoppingBasketKyle.Models.ShoppingBasketViewModel

 @* Format the rendered HTML to have line breaks *@
 @Environment.NewLine
 <table border="1">
     <tr>
        <td>ID</td>
        <td>Name</td>
        <td>Remove</td>
    </tr>

   @for (int count = 0; count < Model.Items.Count; count++)
    {
       <tr>
            <td>@Html.DisplayFor(x => x.Items[count].Id)</td>
            <td>@Html.DisplayFor(x => x.Items[count].Name)</td>
            <td><input type="submit" name="ButtonClicked" value="[email protected](x => x.Items[count].Id)"/></td>
        </tr>
    }
  </table>

  @* Persist ShoppingBasketItems (Collection) property by posting them back *@
  @for (int count = 0; count < Model.Items.Count; count++)
  {
     @Environment.NewLine
     @Html.HiddenFor(x => x.Items[count].Id)
     @Environment.NewLine
     @Html.HiddenFor(x => x.Items[count].Name)
  }

   @* Persist the NextId property by posting it back *@
   @Environment.NewLine
   @Html.HiddenFor(x => x.NextId)

~/ShoppingBasket/Index.cshtml

   @model ShoppingBasketKyle.Models.ShoppingBasketViewModel

   @Html.ValidationSummary(true)

   @using (Html.BeginForm())
   {
      @Html.DisplayForModel()

       <input type="submit" name="ButtonClicked" value="Add" class="btn btn-primary btn--small" />
    }

Любые вопросы, не стесняйтесь спрашивать

ТИА

рукав моря

Теги:
razor
asp.net-mvc-5

1 ответ

0

Мне удалось разобраться в этом, но не понимаю, почему. Проблема, похоже, вызвана вспомогательным методом.HiddenFor() MVC. После поиска SO, похоже, что у него либо есть ошибка, либо по дизайну делает то, что вам неинтересно. Поэтому я обновляю следующее:

~/Views/Shared/DisplayTemplates/ShoppingBasketViewModel.cshtml

@model ShoppingBasketKyle.Models.ShoppingBasketViewModel

@* Format the rendered HTML to have line breaks *@
@Environment.NewLine
<table border="1">
   <tr>
    <td>ID</td>
    <td>Name</td>
    <td>Remove</td>
</tr>

@for (int count = 0; count < Model.Items.Count; count++)
{
    <tr>
        <td>@Html.DisplayFor(x => x.Items[count].Id)</td>
        <td>@Html.DisplayFor(x => x.Items[count].Name)</td>
        <td><input type="submit" name="ButtonClicked" value="[email protected](x => x.Items[count].Id)" /></td>
    </tr>
}

  @* Persist ShoppingBasketItems (Collection) property by posting them back *@
  @for (int count = 0; count < Model.Items.Count; count++)
 {
@Environment.NewLine   
<input type="hidden" id="Items[@count.ToString()].Id" name="Items[@count.ToString()].Id" value="@Model.Items[count].Id" />
@Environment.NewLine
<input type="hidden" id="Items[@count.ToString()].Name" name="Items[@count.ToString()].Name" value="@Model.Items[count].Name" />
 }

 @* Persist the NextId property by posting it back *@
 @Environment.NewLine
 <input type="hidden" id="NextId" name="NextId" value="@Model.NextId" />
 @Environment.NewLine

Я собираюсь написать метод extenstion, чтобы получить имя свойства viewmodel динамически, поэтому, если он будет переименован, мне не придется вручную поддерживать html в представлении

ура

Ещё вопросы

Сообщество Overcoder
Наверх
Меню