ASP.NET MVC DropDownList 选择值问题

Posted

技术标签:

【中文标题】ASP.NET MVC DropDownList 选择值问题【英文标题】:ASP.NET MVC DropDownList Selected Value Problem 【发布时间】:2009-09-16 18:36:43 【问题描述】:

我已经阅读了大量关于这个问题的信息,但我无法弄清楚。

我的视图上有一个用于分页的下拉列表。您选择要访问的页面并提交表单。返回视图时,将显示请求的页面。下拉列表更改以反映新显示的页面。这工作正常。

我的问题是: 我有 2 个提交按钮,一个用于下一页,一个用于上一页。 在控制器中,如果已按下其中一个提交,则 page# 应递增或递减 1。这种情况正在发生,并且正在显示正确的数据页。但是,无论我做什么,下拉列表都不会在显示视图时反映新的页码。

基本上,如果用户更改了下拉菜单,它会在表单提交后发回时反映这些更改。如果我以编程方式更改页面 #,即使显示了正确的数据页面,下拉列表也不会更改。

下面是动作方法:

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);

这里是视图的相关部分:

<input type="submit" value="<" name="PrevPage" />
Page
<%=html.DropDownList("Page",(SelectList)ViewData["pages"]) %>
of
<%=ViewData["pageCount"]%>
<input type="submit" value=">" name="NextPage"  />

请帮忙。

编辑

Pro ASP.NET MVC Framework by Steven Sanderson 的第 333 页:

输入控件如何获取它们的值

每个 [用于渲染输入控件的 HTML 帮助程序] 都试图 通过寻找一个值来填充自己 在以下地方,按此顺序 优先级:

    ViewData.ModelState["controlName"].Value.RawValue value 参数传递给 HTML 帮助方法,或者如果您调用了 不包含值的重载 参数,然后 ViewData.Eval("controlName")

ModelState 是一个临时存储区 ASP.NET MVC 用来保留的 传入的尝试值加上绑定 和验证错误。请注意 它位于优先级列表的顶部, 所以它的值会覆盖你的任何东西 可能会明确设置。这个约定 意味着您可以通过显式 值参数充当助手的 默认值或初始值;但当 之后重新渲染视图 验证失败,助手将 保留任何用户输入的值 偏好该默认值。

我已验证 ViewData.ModelState["Page"].Value.RawValue 确实包含困扰我的意外页码。解决此问题的最佳方法是什么?

【问题讨论】:

+1 真的很好地使用了字符串和模型绑定来对按下的提交按钮进行可读的解析。 @Dan - 谢谢。我是从 Steven Sanderson 的 Pro ASP.NET MVC Framework 中获得的,在向导和多步表单部分(第 396 页) 史蒂文·桑德森的书很不错。 @RichardOD - 这是一本很棒的书!我在一周内读完那本书的封面。我从来没有这样读过技术书籍。除了是一本优秀的 ASP.NET MVC 书籍外,它还非常适合一般的 Web 开发。 【参考方案1】:

问题在于 ModelState 持有下拉列表的传入值。对于 HtmlHelper 输入控件,在输入控件中显示值时,ModelState 的优先级高于显式设置的值。

这是我在解决问题的操作方法中所做的:

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

我很想听听其他解决问题的方法。

【讨论】:

将页码直接放入操作中的模型状态,而不是清除它。您的选择列表将仅从页面列表中生成。【参考方案2】:

在回发之前,点击下一个或上一个按钮,使用 javascript 更改所选值。

【讨论】:

我在问我的问题之前就这样做了,并且解决了它,但为什么它不能正常工作? 浏览器正在缓存用户的选择。通过使用 javascript,您可以在回发之前更改用户选择(以及浏览器对选择的印象)。另一种方法是将一个值放入您的页面标题中,指定不缓存。不过,这可能是也可能不是您需要的…… 浏览器不应该缓存。表单方法是一个 GET。就是说页面参数是在url中发送的,这使得url是唯一的。【参考方案3】:
    您确定保证NextPagePrevPage 中的至少一个将为空吗? (你不会得到像String.Empty 强制递增和递减这样的奇怪东西吗?) 可以将.LastOrDefault() 替换为仅.Last() 并且您确定没有将default(int) 分配给search.Page

【讨论】:

1.) 是的,我确定。 2.) 那行代码与问题无关。【参考方案4】:

下面有没有影响?

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

更换

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

【讨论】:

以上是关于ASP.NET MVC DropDownList 选择值问题的主要内容,如果未能解决你的问题,请参考以下文章

如何给DropDownList控件设置样式(ASP.NET MVC)

Asp.net mvc页面传值-- dropdownlist

在 ASP.NET MVC 2 中实现 DropDownList 的最佳方式?

ASP.NET MVC 使用视图中的值填充 DropDownList

带有 DropDownList 的 ASP.NET MVC 强类型视图

ASP.NET MVC DropDownList 选择值问题