【发布时间】:2009-02-08 01:20:48
【问题描述】:
我的 MVC 应用程序中有两个复选框,它们都是布尔/位字段。 “通知电子邮件”和“通知短信”。
每当我发回服务器并发生错误时,尽管我设置了尝试值,但复选框的状态已消失。
【问题讨论】:
标签: asp.net-mvc
我的 MVC 应用程序中有两个复选框,它们都是布尔/位字段。 “通知电子邮件”和“通知短信”。
每当我发回服务器并发生错误时,尽管我设置了尝试值,但复选框的状态已消失。
【问题讨论】:
标签: asp.net-mvc
为什么不这么简单?
<%=Html.CheckBox("AgreeToRules", (Request.Form["AgreeToRules"] ?? string.Empty).Contains("true"))%>
【讨论】:
这个问题和这个问题一起,
解决了 ASPNET.MVC RC1 的一个非常未记录的特性。我已经搜索了好几个小时才能找到一个好的答案,但找到的很少。
There is a bug,显然,它禁止复选框和单选按钮从 ModelState 保持其状态。我们现在也知道,这两个控件是由 Html 助手专门处理的。
我想出的最好办法就是构建自己的 ViewBinder:
从一个非常简单的角度来看:
<h2>Keep checkbox value between posts</h2>
<% using (Html.BeginForm("update", "checkbox")) {%>
<p><%= Html.CheckBox("a") %></p>
<p><%= Html.CheckBox("b") %></p>
<p><%= Html.TextBox("dummy") %></p>
<input type="submit" value="update" />
<% } %>
与同样简单的控制器相关联:
public class CheckboxController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Update()
{
var binder = new ViewBinder(ViewData, ValueProvider);
binder.UpdateBooleanValues("a", "b");
binder.UpdateMissingValues();
return View("Index");
}
}
还有一个简单的类来完成所有工作:
internal class ViewBinder
{
private readonly IDictionary<string, ValueProviderResult> valueProvider;
private readonly ViewDataDictionary viewData;
public ViewBinder(ViewDataDictionary viewData, IDictionary<string, ValueProviderResult> valueProvider)
{
this.valueProvider = valueProvider;
this.viewData = viewData;
}
public void UpdateMissingValues()
{
foreach (var key in valueProvider.Keys)
{
if (ValueIsMissing(key)) UpdateValue(key);
}
}
public void UpdateBooleanValues(params string[] names)
{
foreach (var name in names)
{
UpdateValue(name, BooleanValueFor(name));
}
}
private bool BooleanValueFor(string name)
{
return valueProvider[name].AttemptedValue != "false";
}
private bool ValueIsMissing(string key)
{
return viewData.ContainsKey(key) == false;
}
private void UpdateValue(string key)
{
var value = valueProvider[key].AttemptedValue;
UpdateValue(key, value);
}
private void UpdateValue(string key, object value)
{
viewData[key] = value;
}
}
【讨论】:
MVC 不像 WebForms 那样具有 ViewState - 这意味着您现在有责任维护这些值。
这将要求您存储复选框是否被选中,然后在页面呈现到您的视图中的浏览器之前再次将该设置应用于复选框。
【讨论】:
亚当,
假设您了解 MVC 不包含处理 Asp.Net 回发的服务器功能,如果您需要向服务器发送一条消息,通知您的应用程序已选中该复选框,那么最好这样做使用 Javascript 和 Ajax 请求。 .Net MVC 包含一个 JQuery Javascript 库,因此这样做可能比您想象的要容易。 Here's 一个 SO 帖子,涵盖了如何在 MVC 中正确使用复选框。
否则,请意识到 MVC 不支持回发,就像 Andrew 上面所说的那样,也不支持 Asp.Net 视图状态。但是,您可以回到旧的视图状态方式,并使用带有一点 javascript 的常规 HTML 隐藏输入元素来维护您的状态。
话虽如此,您可能需要花一点时间阅读此article。许多 MVC 框架假定您将使用 Post -> Redirect -> Get 模式来处理 Web 表单中的用户输入。如果您继续使用当前的回发和视图状态模式,您将来可能会遇到更多问题,例如您当前正在尝试解决的问题。
【讨论】:
您如何指定您的复选框 HTML?除了复选框输入元素之外,绑定还需要一个隐藏的输入元素。 Html.Checkbox 会为你处理这个,或者你可以研究它是怎么做的然后自己做。
【讨论】:
使用 HTML Helper(例如 Html.CheckBox)将在 POST 上自动保持状态。
【讨论】:
Andrei Rinea 部分正确。但我已经完成了 - 是使用帮助程序并将先前的值传递回页面中的数据类(由模型访问等)。它运作良好。
【讨论】:
其他人可能会发现此解决方案很有用:
Maintain state of a dynamic list of checkboxes in ASP.NET MVC
【讨论】: