ASP.NET Core MVC: How to change QueryString param

2019-08-20 00:52发布

问题:

My issue is an aesthetic one. I have the following Controller:

[HttpGet("[action]/{EmployeeTypeID:int?}")]
public IActionResult FilterByType(int EmployeeTypeID = 1)
{ ... }

Which is called when I go to the following routes, for example:

/Employees/FilterByType
/Employees/FilterByType/2

Great. The controller returns the following ViewModel to the View:

public class EmployeesByTypeViewModel
{
    public IEnumerable<Employee> FilteredEmployees { get; set; }
    public IEnumerable<SelectListItem> EmployeeTypes { get; set; }
    public int EmployeeTypeID { get; set; }
}

And my view, has a dropdown that should change the URL param (in order to filter by a different EmployeeType):

@model Tiendas.Models.EmployeesByTypeViewModel  
<h2>Employees</h2>
<form asp-controller="Employees" asp-action="FilterByType" method="GET">
    <select asp-for="EmployeeTypeID" asp-items="Model.EmployeeTypes">
    </select>
    <button type="submit">Filter</button>
</form>
//code displaying filtered employees...

However, when I'm at /Employees/FilterByType and I submit the form it results in, for example:

/Employees/FilterByType?EmployeeTypeID=3

instead of:

/Employees/FilterByType/3

Which is what I want (functionality wise both work). Additionally, if I type the URL above and then submit the form, I get the following:

/Employees/FilterByType/3?EmployeeTypeID=1

How can I get a pretty URL param instead of the QueryString? I'm using attribute routing.

回答1:

You have a form that is making a GET. The browser has no knowledge of your route definition and in accordance with the standards, the value of any form controls are added as query string values.

If you want to generate /Employees/FilterByType/3, then you will need javascript/jquery to generate the url, and location.href to make the redirect, for example

$('form').submit(function(e) {
    e.preventDefault(); // cancel the default action
    baseUrl = '@Url.Action("FilterByType", "Employees")';
    var selectedEmployee = $('#EmployeeTypeID').val();
    location.href = baseUrl + '/' + selectedEmployee; // redirect
});