如何在ASP.NET MVC中维护Html.CheckBox()的状态

时间:2009-02-08 01:20:48

标签: asp.net-mvc

我的MVC应用程序中有两个复选框,它们都是布尔/位字段。 “NotifyEmail”& “NotifySMS”。

每当我回发到服务器并发生错误时,虽然我设置了尝试的值,但是复选框的状态已经消失。

8 个答案:

答案 0 :(得分:7)

为什么不能像这样简单?

<%=Html.CheckBox("AgreeToRules", (Request.Form["AgreeToRules"] ?? string.Empty).Contains("true"))%>

答案 1 :(得分:3)

更新: This is fixed in RC2.

这个问题与这一个一起,

  

Html.Checkbox does not preserve its state in ASP.net MVC

解决了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;
    }
}

答案 2 :(得分:2)

MVC没有像WebForms那样的ViewState - 这意味着你现在有责任维护这些值。

这将要求您存储是否选中了复选框,然后在将视图呈现到视图中的浏览器之前再次将该设置应用于复选框。

答案 3 :(得分:0)

亚当,

假设您了解MVC不包含处理Asp.Net post-backs的服务器功能,如果您需要将消息发送回服务器,通知您的应用程序已选中复选框,那么最好做的是使用Javascript和Ajax请求。 .Net MVC包含一个JQuery Javascript库,所以这样做可能比你想象的要容易。 Here's SO帖子,其中介绍了如何在MVC中正确使用复选框。

否则,意识到MVC不支持回发,并且像上面提到的Andrew一样,也不支持Asp.Net视图状态。但是,您可以回到旧学校的视图状态,并使用常规的HTML隐藏输入元素和一些javascript来维护您的状态。

尽管如此,您可能需要花一点时间阅读article。许多MVC框架假设您将使用Post - &gt;重定向 - &gt;获取处理Web表单中用户输入的模式。如果您继续使用当前的回发和查看状态模式,将来可能会遇到更多问题,例如您当前正在尝试解决的问题。

答案 4 :(得分:0)

您如何指定复选框HTML?除了复选框输入元素之外,绑定还需要隐藏的输入元素。 Html.Checkbox将为您处理此问题,或者您可以研究它是如何做到的并自己完成。

答案 5 :(得分:0)

使用HTML Helper(如Html.CheckBox)会在POST时自动保持状态。

答案 6 :(得分:0)

Andrei Rinea部分正确。但是我已经完成了 - 使用帮助程序并将之前的值传回页面到DataClass(由Model。等访问)。它运作良好。

答案 7 :(得分:0)

其他人可能会觉得这个解决方案很有用:

Maintain state of a dynamic list of checkboxes in ASP.NET MVC