首页 > 解决方案 > 使用下拉菜单将多个搜索条件应用于剃须刀页面列表

问题描述

在 Visual Studio 2019 Web 应用程序 EF Core 中,我有一个带有项目列表的剃须刀页面。每个项目都有几个带有资源名称的列。我希望能够使用多个下拉列表进行过滤。我已经设法构建了页面和过滤器,但它们只有在我在两个下拉列表中都选择一个条目时才起作用。如果我独立使用它们,我不会收到任何错误。两个搜索字符串在 URL 中正确显示/Projects?fosearchString=1&dsmsearchString=0,但如果我只使用其中一个下拉条目,结果不会更新。我希望下拉过滤器独立工作并一起工作(例如,仅 FO、仅 DSM、FO 和 DSM 一起)。我怎样才能做到这一点?

我有资源模型:

    public class Resource
    {
        [Display(Name = "ID")]
        public int Id { get; set; }

        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Display(Name = "Long Name")]
        public string LongName { get; set; }

        [Display(Name = "Active")]
        public bool IsActive { get; set; }
        public ICollection<ProjectResource> ProjectResources { get; set; }
    }

项目模型:

    public class Project
    {
        [Display(Name = "ID")]
        public int Id { get; set; }

        [Display(Name = "PID")]
        public int PID { get; set; }

        [Display(Name = "Name")]
        public string ProjectName { get; set; }

        [Display(Name = "Forecast Owner")]
        public int FOId { get; set; }
        public Resource Resource { get; set; }

        [Display(Name = "DSM")]
        public int DSMId { get; set; }
        public Resource DSMResource { get; set; }

        public ICollection<ProjectResource> ProjectResources { get; set; }

    }

index.cshtml.cs:

        public IList<Project> Project { get; set; }
        public IList<Resource> Resources { get; set; }
        public SelectList FOOptions { get; set; }
        public string CurrentFOFilter { get; set; }
        public SelectList Options { get; set; }
        public string CurrentDSMFilter { get; set; }

        public async Task<IActionResult> OnGetAsync(List<int> fosearchString, List<int> dsmsearchString)
        {
            FOOptions = new SelectList(_context.Resource, nameof(Resource.Id), nameof(Resource.LongName));
            List<int> CurrentFOFilter = fosearchString;
            Options = new SelectList(_context.Resource, nameof(Resource.Id), nameof(Resource.LongName));
            List<int> CurrentDSMFilter = dsmsearchString;
            if (fosearchString.Count == 0 || fosearchString[0] == 0 && dsmsearchString.Count == 0 || dsmsearchString[0] == 0)
            {
                Resources = await _context.Resource.ToListAsync();
                Project = await _context.Project
                .Include(p => p.Resource).ToListAsync();
            }
            else
            {
                Resources = await _context.Resource.ToListAsync();
                Project = await _context.Project
                    .Include(p => p.Resource)
                    .Where(s => fosearchString.Contains(s.FOId) && dsmsearchString.Contains(s.DSMId))
                .ToListAsync();

            }
            return Page();
        }

index.cshtml:

<form asp-page="./Index" method="get">
    <div class="dropdown col-4 no-gutters">
        <div class="input-group mb-3">
            <select class="custom-select" name="fosearchString" value="@Model.CurrentFOFilter" asp-items="Model.FOOptions" selected="selected"><option value="0">Filter by FO...</option></select><text>&nbsp;</text>
            <select class="custom-select" name="dsmsearchString" value="@Model.CurrentDSMFilter" asp-items="Model.Options" selected="selected"><option value="0">Filter by DSM...</option></select><text>&nbsp;</text>
        </div>
        <input type="submit" value="Filter" class="btn btn-primary" /><text>&nbsp;</text><input type="submit" action="/Projects/Index" value="Back to full List" class="btn btn-primary" />
    </div>
</form>
<br />
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Project[0].PID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Project[0].ProjectName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Project[0].FOId)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Project[0].DSMId)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Project)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.PID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ProjectName)
                </td>
                <td>
                    @{
                        var foresource = Model.Resources.FirstOrDefault(r => r.Id == item.FOId);
                    }
                    @foresource.LongName
                </td>
                <td>
                    @{
                        var dsmresource = Model.Resources.FirstOrDefault(r => r.Id == item.DSMId);
                    }
                    @dsmresource.LongName
                </td>

我使用名为 ProjectVM 和 ResourceVM 的两个视图模型将这两个模型组合在一起,并且通过 ProjectResource 类在两个模型之间建立多对多关系。

标签: asp.net-corefilterdrop-down-menurazor-pages

解决方案


问题在于您的ifandelse条件,此外,您需要添加括号,因为&&||.

您可以随时添加断点来检查过滤时它进入的条件。

下面一个可行的解决方案是将第一个选项值设置为,""而不是0更方便地搜索所有:

索引.cshtml:

<div class="input-group mb-3">
        <select class="custom-select" name="fosearchString" value="@Model.CurrentFOFilter" asp-items="Model.FOOptions" selected="selected"><option value="">Filter by FO...</option></select><text>&nbsp;</text>
        <select class="custom-select" name="dsmsearchString" value="@Model.CurrentDSMFilter" asp-items="Model.Options" selected="selected"><option value="">Filter by DSM...</option></select><text>&nbsp;</text>
    </div>

索引.cshtml.cs:

public async Task<IActionResult> OnGetAsync(List<int> fosearchString, List<int> dsmsearchString)
    {
        FOOptions = new SelectList(_context.Resource, nameof(Resource.ID), nameof(Resource.LongName));
        List<int> CurrentFOFilter = fosearchString;
        Options = new SelectList(_context.Resource, nameof(Resource.ID), nameof(Resource.LongName));
        List<int> CurrentDSMFilter = dsmsearchString;

        if (fosearchString.Count == 0 && dsmsearchString.Count == 0)
        {
            Resources = await _context.Resource.ToListAsync();
            Project = await _context.Project.Include(p => p.Resource).ToListAsync();
        }
        else if(fosearchString.Count != 0 && dsmsearchString.Count == 0)
        {
            Resources = await _context.Resource.ToListAsync();
            Project = await _context.Project
                .Include(p => p.Resource)
                .Where(s => fosearchString.Contains(s.FOId))
            .ToListAsync();
        }
        else if (fosearchString.Count == 0 && dsmsearchString.Count != 0)
        {
            Resources = await _context.Resource.ToListAsync();
            Project = await _context.Project
                .Include(p => p.Resource)
                .Where(s => dsmsearchString.Contains(s.DSMId))
            .ToListAsync();
        }
        else
        {
            Resources = await _context.Resource.ToListAsync();
            Project = await _context.Project
                .Include(p => p.Resource)
                .Where(s => fosearchString.Contains(s.FOId) && dsmsearchString.Contains(s.DSMId))
            .ToListAsync();

        }
        return Page();
    }

推荐阅读