【问题标题】:ASP.NET Core MVC filtering: How can I send multiple value to action?ASP.NET Core MVC 过滤:如何将多个值发送到操作?
【发布时间】:2021-04-07 09:52:18
【问题描述】:

我想在我的电子商务项目中过滤产品,但我有一个问题:我希望我的过滤动态改变,我从选定的列表中选择一个品牌并完成必要的过滤。当第二个过滤器完成后,我的第一个过滤器被重置,最后一个过滤器变为有效。

我需要这样的 URL 结构:

/?SelectedVendor=Asus&SelectedMemory=4+GB

FilterViewModel.cs

public class FilterViewModel
    {
        public List<string> Vendors { get; set; }
        public List<string> Memories { get; set; }
        public string SelectedVendor { get; set; }
        public string SelectedMemory { get; set; }
    }

CategoryController.cs

    [HttpGet]
    public ViewResult Gaming(int productPage = 1, FilterViewModel model=null)
    {
        
        ProductListViewModel productList = new ProductListViewModel()
        {
            Products =
                _productService.GetProductsByCategoryId(1).OrderBy(p => p.Id).Skip((productPage - 1) * pageSize).Take(pageSize),
            FilterTypes = new FilterViewModel()
            {
                Vendors = _productService.Products.Select(I => I.Vendor).Distinct().OrderBy(I => I).ToList(),
                Memories = _productService.Products.Select(I => I.MemoryCapacity).Distinct().OrderBy(I => I).ToList(),
            }
        };


        if (!string.IsNullOrEmpty(model.SelectedVendor))
        {
            productList.Products = productList.Products.Where(I => I.Vendor.Contains(model.SelectedVendor));
            productList.FilterTypes.Memories = productList.Products.Select(I => I.MemoryCapacity).Distinct()
                .OrderBy(I => I).ToList();
        }

        if (!string.IsNullOrEmpty(model.SelectedMemory))
        {
            productList.Products = productList.Products.Where(I => I.MemoryCapacity == model.SelectedMemory);
        }

        return View(productList);
    }

FilterPartial.cshtml

<div class="col-md-3">
        <div class="filter filter-first">
            <h6 class="font-weight-bold">Brand</h6>

            <form method="get" asp-controller="@controllerName" asp-action="@actionName">

                @foreach (var vendor in Model.Vendors)
                {
                    <div class="mt-2 mb-2 pl-2">
                        <input type="submit" value="@vendor" asp-for="SelectedVendor"/>
                    </div>
                }


                <h6 class="font-weight-bold">Memory</h6>
                @foreach (var memory in Model.Memories)
                {
                    <div class="mt-2 mb-2 pl-2">
                        <input type="submit" asp-for="SelectedMemory" value="@memory"/>
                    </div>
                }
            </form>

        </div>
    </div>

【问题讨论】:

  • 这是客户端工作。您必须使用 JavaScript 来完成。

标签: c# .net asp.net-core .net-core asp.net-core-mvc


【解决方案1】:

这是一个将 SelectedVendor 和 SelectedMemory 都传递给操作的演示:

TestFilter.cshtml:

@await Html.PartialAsync("Partial", Model.FilterTypes)
<script>
    function addSelectedVendor(i) {
        $("#SelectedVendor").val($(i).val());
        $("#form1").submit();
    }
    function addSelectedMemory(i) {
        $("#SelectedMemory").val($(i).val());
        $("#form1").submit();
    }
    </script>

部分.cshtml:

<form id="form1" method="get" asp-controller="Test" asp-action="TestFilter">

    @foreach (var vendor in Model.Vendors)
    {
        <div class="mt-2 mb-2 pl-2">
            <input type="button" value="@vendor" onclick="addSelectedVendor(this)" />
        </div>
    }


    <h6 class="font-weight-bold">Memory</h6>
    @foreach (var memory in Model.Memories)
    {
        <div class="mt-2 mb-2 pl-2">
            <input type="button" value="@memory" onclick="addSelectedMemory(this)" />
        </div>
    }
    <input hidden asp-for="SelectedVendor"/>
    <input hidden asp-for="SelectedMemory"/>
</form>

TestController(我用假数据来测试):

 [HttpGet]
            public IActionResult TestFilter(FilterViewModel model)
            {
                ProductListViewModel productList = new ProductListViewModel {  FilterTypes=new FilterViewModel()};
                productList.FilterTypes.Vendors = new List<string> { "Apple", "Asus", "Dell", "Lenovo", "MSI" };
                productList.FilterTypes.Memories = new List<string> { "16GB", "4GB", "8GB"};
    
                return View(productList);
            }

结果:

【讨论】:

    【解决方案2】:

    您可以在 get 方法中按列表过滤。

    你应该像这样改变get方法

       public virtual IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = DbSet;
    
            if (filter != null) query = query.Where(filter);
    
            if (includeProperties != null)
                foreach (var includeProperty in includeProperties.Split
                    (new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                    query = query.Include(includeProperty);
    
    
            if (orderBy != null)
                return orderBy(query).ToList();
            return query.ToList();
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 2016-07-21
      • 1970-01-01
      相关资源
      最近更新 更多