I have an asp.net core 3.1 mvc project where I have a search page (view). I am persisting search, filter and sort criteria values via Session data. This works fine, and persists data correctly, but the querystring does not contain all the information I need it to.
Values for the filters and search are selected via a form, and submit button, but sorting is selected by clicking the column headers in the search results. e.g.:
<form asp-controller="Companies" asp-action="Index" method="get">
<p>
<label>Company Name: </label>
<select asp-for="CompanyName" asp-items="Model.CompanyName">
<option value="">All</option>
</select>
<input type="submit" value="Find" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
<a asp-action="Index" asp-route-sortOrder="CompanyName">@Html.DisplayNameFor(model => model.CompaniesListViewModelList[0].CompanyName)</a>
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.CompaniesListViewModelList)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
If the clicks in the header to change the sort order, none of the querystring values for the filters etc appear in the querystring.
The reason I need this is so that a link can be sent to someone else.
So the question is, how do I get all the used querystring values to appear in the querystring?
In the Index action method, you could use ViewBag or ViewData to store the current search value (the CompanyName), then transfer it to the view page:
Then, for the sort links, you could use asp-route-{value}
to add the current search value as the route parameter, and bind values via the ViewData or ViewBag. Code like this:
<a asp-action="Index" asp-route-CompanyName="@ViewData["CurrentFilter"]" asp-route-sortOrder="@ViewData["CompanyNameSortParm"]">CompanyName</a>
The sample code as below:
Models:
public class Employee
{
public int EmployeeId { get; set; }
public string EmployeeName { get; set; }
public string CompanyName { get; set; }
}
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public List<Employee> Employees { get; set; }
}
public class EmployeeVM
{
public string CompanyName { get; set; }
public List<Company> AllCompanies { get; set; }
public List<Employee> Employees { get; set; }
}
Controller:
public class CompaniesController : Controller
{
public IActionResult Index(string sortOrder, string CompanyName)
{
ViewData["CompanyNameSortParm"] = String.IsNullOrEmpty(sortOrder) ? "companyname_desc" : "";
ViewData["CurrentFilter"] = CompanyName;
var employees = from s in repo.GetEmployees()
select s;
if (!String.IsNullOrEmpty(CompanyName))
{
employees = employees.Where(s => s.CompanyName.Contains(CompanyName));
}
switch (sortOrder)
{
case "companyname_desc":
employees = employees.OrderByDescending(s => s.CompanyName);
break;
default:
employees = employees.OrderBy(s => s.EmployeeId);
break;
}
EmployeeVM vm = new EmployeeVM();
vm.Employees = employees.ToList();
vm.AllCompanies = repo.GetAllCompanies().ToList();
return View(vm);
}
}
Index Views:
@model netcore3.Data.EmployeeVM
<form asp-controller="Companies" asp-action="Index" method="get">
<p>
<label>Company Name: </label>
<select asp-for="CompanyName" asp-items="@(new SelectList(Model.AllCompanies, "CompanyName","CompanyName"))">
<option value="">All</option>
</select>
<input type="submit" value="Find" />
</p>
</form>
<table class="table">
<thead>
<tr>
<th>
EmployeeName
</th>
<th>
<a asp-action="Index" asp-route-CompanyName="@ViewData["CurrentFilter"]" asp-route-sortOrder="@ViewData["CompanyNameSortParm"]">CompanyName</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Employees)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.EmployeeName)
</td>
<td>
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.EmployeeId">Edit</a> |
<a asp-action="Details" asp-route-id="@item.EmployeeId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.EmployeeId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
The result like this:
Reference:
Tutorial: Add sorting, filtering, and paging - ASP.NET MVC with EF Core