Как составить список товаров по категориям в ASP.NET MVC?

#c# #asp.net-mvc #postgresql #razor

#c# #asp.net-mvc #postgresql #razor

Вопрос:

Я пытаюсь составить список товаров по значению категории. Значение категории — это описание товара, если товар представляет собой яблоко, категория будет Фруктовой. Итак, я хочу, чтобы пользователь мог выбрать категорию, нажать кнопку и перечислить все товары с той же категорией. Я пытаюсь сделать это, выбрать категорию и список по категориям в одном представлении.

Модель:

 public partial class product
{
    int id {get; set}
    string name {get; set}
    string category {get; set;}
}
  

Контроллер:

 [HttpGet]
public ActionResult ListByCat()
{
    List<SelectListItem> lst = new List<SelectListItem>();
        lst.Add(new SelectListItem() { Text = "Fruits", Value = "fruits" });
        lst.Add(new SelectListItem() { Text = "Hardware", Value = "hardware"});
        lst.Add(new SelectListItem() { Text = "Vegetables", Value = "vegetables"});

        ViewBag.category = lst;

        return View();
 }

 [HttpPost]
 public ActionResult listByCat(product prod)
    {
        using (inventarioEntitiesDBA dc = new inventarioEntitiesDBA())
        {
            return View(dc.product.Where(a => a.category == prod.category).ToList());
        }
            
    }
  

И представление:

 @model regMVC.Models.product

@{
      ViewBag.Title = "listByCat";
 }

  <h2>listByCat</h2>

  @using (Html.BeginForm())
  {
      <div class="form-group">
             @Html.LabelFor(model => model.category, htmlAttributes: new { @class = "control- label col-md-2" })

    <div class="col-md-10">
        @Html.DropDownList("category", null, htmlAttributes: new { @class = "form-control" })
        @Html.ValidationMessageFor(model => model.category, "", new { @class = "text-danger" })
    </div>
</div>

<div class="form-group">
    <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="List by Category" class="btn btn-default" />
    </div>
</div>
  

Комментарии:

1. Вам нужно что-то, чтобы сохранить ваши результаты после операции POST. Вместо отправки модели в методе get вы можете отправить ViewModel . Эта ViewModel содержит ваши категории и список <Product> для вашего результата

Ответ №1:

ViewModel

 public class ListByCatViewModel
    {
        //This hold the selected value in post action
        public string SelectedCategory { get; set; }
        public List<SelectListItem> Categories { get; set; } = new List<SelectListItem>();
        public List<Product> SearchResults { get; set; } = new List<Product>();
    }
  

listByCat() ПОЛУЧАЕТ действие, здесь мы передаем ViewModel в представление

 public ActionResult listByCat()
 {
   ListByCatViewModel listByCatViewModel = new ListByCatViewModel();
   listByCatViewModel.Categories = buildCategories();
            
   return View(listByCatViewModel);
 }
  

Теперь действие POST, поиск результата из базы данных, я издеваюсь над результатом из списка

  [HttpPost]
 public ActionResult listByCat(ListByCatViewModel listByCatViewModel)
        {
            if (ModelState.IsValid)
            {
                if (listByCatViewModel.SelectedCategory != null)
                {
                    //Binding dropdown again
                    listByCatViewModel.Categories = buildCategories(listByCatViewModel.SelectedCategory);

                    var products = mockProductCollection();
                    var results = products.FindAll(x => x.category.ToLower() == 
                                       listByCatViewModel.SelectedCategory.ToLower());
                    listByCatViewModel.SearchResults = results;
                }
            }
            return View(listByCatViewModel);
        }
  

Мой вспомогательный метод для заполнения выпадающего списка и списка продуктов

  private List<SelectListItem> buildCategories(string selectedItem = "")
        {
            List<SelectListItem> lst = new List<SelectListItem>();

            lst.Add(new SelectListItem() { Text = "Fruits", Value = "fruits" });
            lst.Add(new SelectListItem() { Text = "Hardware", Value = "hardware" });
            lst.Add(new SelectListItem() { Text = "Vegetables", Value = "vegetables" });

            if (!string.IsNullOrEmpty(selectedItem))
            {
                lst.Find(x => x.Value.ToLower() == selectedItem.ToLower()).Selected = true;
            }
            return lst;
        }
        private List<Product> mockProductCollection()
        {
            List<Product> products = new List<Product>() { 
                new Product(){id=1,category="fruits",name="Apple"},
                new Product(){id=2,category="fruits",name="Banana"},
                new Product(){id=3,category="hardware",name="Screws"},
                new Product(){id=4,category="hardware",name="Bolt"},
                new Product(){id=5,category="vegetables",name="Carrot"},
                new Product(){id=6,category="vegetables",name="Cucumber"}
            };
            return products;
        }
  

и, наконец, представление

 @model NETMVC.ViewModel.ListByCatViewModel
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.LabelFor(model => model.Categories, htmlAttributes: new { @class = "control- label col-md-2" })

        <div class="col-md-10">
            @Html.DropDownListFor(model => model.SelectedCategory,Model.Categories, htmlAttributes: new { @class = "form-control" })
            @Html.ValidationMessageFor(model => model.Categories, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="List by Category" class="btn btn-default" />
        </div>
    </div>
}

@if (Model.SearchResults != null amp;amp; Model.SearchResults.Count > 0)
{

<ul>
    <li>Search Results</li>
    @foreach (var product in Model.SearchResults)
    {
        <li>@product.name</li>
    }
</ul>
}
  

Комментарии:

1. Отличное решение @Raju Спасибо