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

时间:2022-02-28 09:53:23

I have two checkboxes in my MVC app which are both boolean / bit fields. "NotifyEmail" & "NotifySMS".

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

Whenever I post back to the server and an error occurs, the state of the checkbox is gone event though I set attempted values.

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

8 个解决方案

#1


Why not something as simple as this?

为什么不这么简单呢?

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

#2


Update: This is fixed in RC2.

更新:这在RC2中已修复。

This question together with this one,

这个问题和这一个一起,

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

Html.Checkbox不保留其在ASP.net MVC中的状态,

addresses a very undocumented feature of the ASPNET.MVC RC1. I have been searching around for hours to find a good answer, but there are very few to find.

解决了ASPNET.MVC RC1的一个非文档特征。我一直在寻找好几个小时找到一个好的答案,但很少有人找到。

There is a bug, apparently, which prohibit checkboxes and radiobuttons to maintain their state from ModelState. As we also know by now, is that these two controls are handled specially by the Html helpers.

显然,有一个错误禁止复选框和单选按钮从ModelState维护其状态。我们现在也知道,这两个控件是由Html助手专门处理的。

The best I managed to come up with, was to build my own ViewBinder:

我设法得到的最好的,就是构建我自己的ViewBinder:

From a very simple view:

从一个非常简单的看法:

<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" />

<% } %>

Associated with an equally simple controller:

与同样简单的控制器相关联:

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

And a simple class to make it all work:

还有一个简单的类可以使它全部工作:

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

#3


MVC does not have ViewState like WebForms does - this means that you now have the responsibility of maintaining those values.

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

This will require that you store whether or not the checkbox was checked and then applying that setting to the checkbox again before the page is rendered to the browser in your View.

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

#4


Adam,

Assuming you understand that MVC does not include server functionality to handle Asp.Net post-backs, If you need to send a message back to the server that informs your application that the check box was checked, then it's probably best to do that with Javascript and an Ajax request. .Net MVC includes a the JQuery Javascript library so doing this may be easier then you think. Here's an SO post that kind of covers how to use checkboxes correctly in MVC.

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

Otherwise, realize that MVC doesn't support post-back, and like Andrew said above, doesn't support Asp.Net view-state either. However, you could go back to the old school way of view-state and use a regular HTML hidden input element with a little bit of javascript to maintain your state.

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

That all being said, you might want to take a minute to read this article. A lot of MVC frameworks assume that you will be using the Post -> Redirect -> Get pattern for handling user input in your web forms. If you continue to use your current pattern of post-back and view state, you may run into more problems in the future like the one you're currently trying to solve.

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

#5


How are you specifying your checkbox HTML? Binding will require a hidden input element in addition to the checkbox input element. Html.Checkbox will handle this for you, or you can study how it does it and do it yourself.

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

#6


Using an HTML Helper such as Html.CheckBox will persist the state automatically on POST.

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

#7


Andrei Rinea is partially right. But I have done - is use the helpers and pass back into the page the previous values into the DataClass (accessed by Model. etc). It works well.

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

#8


Others may find this solution useful:

其他人可能会发现此解决方

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

维护ASP.NET MVC中动态的复选框列表的状态

#1


Why not something as simple as this?

为什么不这么简单呢?

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

#2


Update: This is fixed in RC2.

更新:这在RC2中已修复。

This question together with this one,

这个问题和这一个一起,

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

Html.Checkbox不保留其在ASP.net MVC中的状态,

addresses a very undocumented feature of the ASPNET.MVC RC1. I have been searching around for hours to find a good answer, but there are very few to find.

解决了ASPNET.MVC RC1的一个非文档特征。我一直在寻找好几个小时找到一个好的答案,但很少有人找到。

There is a bug, apparently, which prohibit checkboxes and radiobuttons to maintain their state from ModelState. As we also know by now, is that these two controls are handled specially by the Html helpers.

显然,有一个错误禁止复选框和单选按钮从ModelState维护其状态。我们现在也知道,这两个控件是由Html助手专门处理的。

The best I managed to come up with, was to build my own ViewBinder:

我设法得到的最好的,就是构建我自己的ViewBinder:

From a very simple view:

从一个非常简单的看法:

<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" />

<% } %>

Associated with an equally simple controller:

与同样简单的控制器相关联:

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

And a simple class to make it all work:

还有一个简单的类可以使它全部工作:

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

#3


MVC does not have ViewState like WebForms does - this means that you now have the responsibility of maintaining those values.

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

This will require that you store whether or not the checkbox was checked and then applying that setting to the checkbox again before the page is rendered to the browser in your View.

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

#4


Adam,

Assuming you understand that MVC does not include server functionality to handle Asp.Net post-backs, If you need to send a message back to the server that informs your application that the check box was checked, then it's probably best to do that with Javascript and an Ajax request. .Net MVC includes a the JQuery Javascript library so doing this may be easier then you think. Here's an SO post that kind of covers how to use checkboxes correctly in MVC.

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

Otherwise, realize that MVC doesn't support post-back, and like Andrew said above, doesn't support Asp.Net view-state either. However, you could go back to the old school way of view-state and use a regular HTML hidden input element with a little bit of javascript to maintain your state.

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

That all being said, you might want to take a minute to read this article. A lot of MVC frameworks assume that you will be using the Post -> Redirect -> Get pattern for handling user input in your web forms. If you continue to use your current pattern of post-back and view state, you may run into more problems in the future like the one you're currently trying to solve.

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

#5


How are you specifying your checkbox HTML? Binding will require a hidden input element in addition to the checkbox input element. Html.Checkbox will handle this for you, or you can study how it does it and do it yourself.

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

#6


Using an HTML Helper such as Html.CheckBox will persist the state automatically on POST.

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

#7


Andrei Rinea is partially right. But I have done - is use the helpers and pass back into the page the previous values into the DataClass (accessed by Model. etc). It works well.

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

#8


Others may find this solution useful:

其他人可能会发现此解决方

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

维护ASP.NET MVC中动态的复选框列表的状态