ASP.NET MVC DropDownList Selected Value Problem

I have read a ton about this problem, but I cannot figure it out.

I have a dropdownlist on my view that is used for paging. You choose the page you want to go to and the form gets submitted. When the view is returned, the requested page is shown. The dropdownlist changes to reflect the newly shown page. This is working fine.

My problem is this:
I have 2 submit buttons, one for next page and one for prev page.
In the controller, if one of the submits have been pressed, the page# should be incremented or decremented by 1. This is happening, and the correct page of data is being shown. But, the dropdown list will not, NO MATTER WHAT I DO, reflect the new page number when the view is shown.

Basically, if the dropdown is changed by the user, it will reflect those changes when it is sent back after a form submission. If I change the page # programmatically, the dropdown will not change, even though the correct page of data gets shown.

Here is the action method:

public ActionResult Results(TechSearch search, string NextPage, string PrevPage)
{
    if (NextPage != null) search.Page++;
    if (PrevPage != null) search.Page--;

    int resultCount = search.GetResultCount(Desk);

    List<int> pages = new List<int>();
    int pageCount = (int)Math.Ceiling((decimal)resultCount / search.PageSize);
    for (int i = 1; i <= pageCount; i++) pages.Add(i);        

    ViewData["pages"] = new SelectList(pages, search.Page);            
    ViewData["pageCount"] = pageCount;
    
    return View(search);
}

And here is the relevant part of the view:
<input type="submit" value="<" name="PrevPage" />
Page
<%=Html.DropDownList("Page",(SelectList)ViewData["pages"]) %>
of
<%=ViewData["pageCount"]%>
<input type="submit" value=">" name="NextPage"  />

Please help.

EDIT

Page 333 of Pro ASP.NET MVC Framework by Steven Sanderson:

How Input Controls Get Their Values

Each of [the HTML Helpers for Rendering Input Controls] tries to
populate itself by looking for a value
in the following places, in this order
of priority:

  1. ViewData.ModelState[“controlName”].Value.RawValue
  2. value parameter passed to HTML helper method, or if you’ve called an
    overload that doesn’t include a value
    parameter, then
    ViewData.Eval(“controlName”)

ModelState is a temporary storage area
that ASP.NET MVC uses to retain
incoming attempted values plus binding
and validation errors. Notice that
it’s at the top of the priority list,
so its values override anything you
might set explicitly. This convention
means that you can pass an explicit
value parameter to act as the helper’s
default or initial value; but when
rerendering the view after a
validation failure, the helper will
retain any user-entered value in
preference to that default.

I have verified that ViewData.ModelState[“Page”].Value.RawValue does contain the unexpected page number that is pestering me. What’s the best way to work around this?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

The problem was that ModelState was holding the dropdownlist’s passed in value. For the HtmlHelper input controls, ModelState is given priority over explicitly set values when displaying a value in the input control.

Here is what I have done in my action method to fix the problem:

ModelState.Remove("Page");
return View(search);

I am interested in hearing other ways of fixing my problem.

Method 2

Change the selected value with javascript on the click of the next or previous button, right before your postback.

Method 3

  1. Are you sure that you are guaranteed that at least one of NextPage or PrevPage will be null? (And you don’t get anything weird like String.Empty forcing an increment and decrement?)
  2. Could .LastOrDefault() be replaced with just .Last() and you are sure that you are not assigning default(int) to search.Page?

Method 4

Does the below have any effect?

ViewData["pages"] = new SelectList(pages, 
                                   pages.FirstOrDefault(p => p == search.Page ));

Replacing
ViewData["pages"] = new SelectList(pages, search.Page);


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x