Question

I have a page that displays a list of people. It can be sorted on first and last name. To search for people, I have the following Razor form:

@using (Html.BeginForm("Index", "Persons", new { sort = ViewBag.Sort }, FormMethod.Get))
{
    <p>
        Search: @Html.TextBox("search", ViewBag.Search as string)
        <input type="submit" value="Search" />
    </p>
}

ViewBag.Search and ViewBag.Sort contains the last used search and sort routeValues. When I sort the list of people on first name, the form gets rendered in HTML like this:

<form action="/persons?sort=firstname" method="get">
    <p>
        Search: <input id="search" name="search" type="text" value="" />
        <input type="submit" value="Search" />
    </p>
</form>

As intended, ?sort=firstname is included in the action. However, when I press the submit button (Search), the sort parameter is lost. The new url only has ?search=.... How can I fix this?

Was it helpful?

Solution

When you look at the output html you would get something like this :

<form action="/persons/index?sort=asc" method="get">
    <p>
        <input type="text" name="search" />
        <input type="submit" value="Search" />
    </p>
</form>

This seems completely legit, you would expect a behaviour like appending the query of post inputs. However this is limited by HTTP specification. The query string of a form post action wont be appended. That is why your query parameters wont work at your server side. However i what would expect from the Asp.net to get the parameters for the form to the hidden fields automatically which it doesnt right now.

As a proper solution you have to put the input , in the form , so you can use hidden field to do this like :

@using (Html.BeginForm("Index", "Persons", FormMethod.Get))
{
   @Html.Hidden("sort",ViewBag.Sort)
   <p>
      Search: @Html.TextBox("search", ViewBag.Search as string)
      <input type="submit" value="Search" />
   </p>
}

OTHER TIPS

You need to store the value of sort somewhere in the form, in order for it to be included as part of the submit. You could try a hidden input:

@using (Html.BeginForm("Index", "Persons"))
{
    <input type="hidden" id="sort" value="firstname" />
    <p>
        Search: @Html.TextBox("search", ViewBag.Search as string)
        <input type="submit" value="Search" />
    </p>
}

You may need to tweak how the value of sort is retrieved from, I put firstname as an example, but when you submit the form, sort will be included in the payload e.g.

[HttpPost]
public ActionResult Index(string sort, string search)
{
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top