使用 Request.Form 确定在 CheckBoxList 中选择了哪些项目

Posted

技术标签:

【中文标题】使用 Request.Form 确定在 CheckBoxList 中选择了哪些项目【英文标题】:Determining which items are selected in CheckBoxList using Request.Form 【发布时间】:2016-10-07 23:57:22 【问题描述】:

使用问题here 中显示的方法,我可以从我的CheckBoxList 中获取所选项目的值:

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                        where key.Contains(cbl.ID)
                        select Request.Form.Get(key);

然后我可以遍历结果:

foreach (var item in selectedCheckBoxItems)



问题在于item 只是发布的值,对于复选框来说,它只是字符串“on”。

我需要能够通过索引或其他方法来确定哪个项目“打开”。

问题:如何使用Request.Form 确定CheckBoxList 中的哪些项目被选中?

这是我的 CheckBoxList 定义:

<asp:CheckBoxList runat="server" ID="cblAnimalType" SelectionMode="Multiple" DataTextField="OptionText" DataValueField="OptionId"  AutoPostBack="True"/>

项目从后面的代码添加到列表中:

DataTable dt = GetData(SqlGetListOptions, paramList);
cbl.DataSource = dt;
cbl.DataBind();

另一个要知道的重要事情是ViewStateMode="Disabled",所以我必须使用Request.Form 来获取所选项目。


作为对评论的回应,下面是 CheckBoxList 的 html 呈现方式:


@Leopard 指出他看到 HTML 中呈现的值在我的情况下没有出现。 AdamE 对this question 的回答解释了原因。我在 web.config 中有以下行:

<pages validateRequest="false" controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">

这解释了为什么我看到“on”而不是所选项目的实际值。我无法在不验证它不会破坏其他内容的情况下将兼容性从 web.config 中删除,但似乎如果该设置可以安全删除,则可以从代码隐藏中访问复选框列表值。

【问题讨论】:

你是说当你设置ViewStateMode="Enabled"然后得到CheckListBox的项目的检查状态工作正常吗? 我是说 View State 被禁用,所以我必须使用 Request.Form。如果启用了视图状态,我只会从控件的视图状态中获取所选项目,例如 this "On" 是DataValueField 用于CheckBoxList 中的所有项目? 很抱歉提出这个问题:为什么不为该列表启用 ViewState? @ConnorsFan - 有多种原因。一个是远程用户在尝试与视图状态臃肿的表单交互时面临的性能问题。 【参考方案1】:

当您将checkboxListDatabase 绑定到OptionId 字段时,您可以检查选择了哪些checkboxes 并将它们的值存储在List&lt;int&gt; 中,假设它们的值为int

然后,当您再次填充checkboxlist 时,您可以检查之前存储的list 中存在哪个value,并且基于value,您可以select 相关的checkbox

这是一个示例代码

List<int> SelectedCheckBoxes = new List<int>();
var selectedCheckBoxItems = from key in Request.Form.AllKeys
                                    where key.Contains(cblAnimalType.ID)
                                    select Request.Form.Get(key);
foreach (var item in selectedCheckBoxItems)

  SelectedCheckBoxes.Add(int.Parse(item.ToString()));

然后当你populatecheckboxlist你可以找到value的项目并选择它们

foreach (ListItem listItem in cblAnimalType.Items)

  if (SelectedCheckBoxes.Contains((int.Parse(listItem.Value))))
   
     listItem.Selected = true;
   

您可能需要将SelectedCheckBoxes List 存储在session 中,具体取决于您填充checkboxlist 的方式。

更新

根据与您的讨论,您使用的是Asp.net 4.0,但您的checkboxes 没有应该存在的value attribute

发生这种情况是因为您正在使用controlRenderingCompatibilityVersion="3.5",因为您已经在使用Asp.Net 4.0,因此不再需要它。

所以从web.congif 中删除这一行将解决问题,您将能够获得value of checkbox 而不仅仅是获得on

<pages controlRenderingCompatibilityVersion="3.5" />

【讨论】:

为什么假定该值是整数?存储List&lt;string&gt; SelectedValues 并避免int.Parse(即使该值实际上是整数)不是更简单、更安全吗? @ConnorsFan 因为该值绑定到属性ID,这似乎是int。而int.parse 因为.Valuestringitemvar 类型。 @MairajAhmad - 这个解决方案的问题是 item.ToString() 为“on”,无法解析为 Int,也无法与列表中的项目相关联( “on”不会告诉我选择了哪个复选框)。您可以在我的原始问题中看到这一点,我在其中发布了屏幕截图,显示了 foreach 中 item 的内容,它迭代了 selectedCheckBoxItems 我使用了相同的代码并且能够做到这一点。你试过这个吗? 您在 aspc 中显示 cblanimaltype 但在 c# 代码中使用 cbl.id 的一件事是正确的。【参考方案2】:

我想到了一种方法,即在结果中添加键。由于获取索引所需的字符串解析,我对这种方法并不完全满意。也许其他人有更好的方法?

总体思路是在结果中添加key:

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                        where key.Contains(cbl.ID)
                        select new Value = Request.Form.Get(key), Key = key;
foreach (var item in selectedCheckBoxItems)

   var val = item.Value;
   var key = item.Key;

然后我可以解析键以找到索引,这是我设置所选选项所需要的:

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                        where key.Contains(cbl.ID)
                        select new Value = Request.Form.Get(key), Key = key;

string[] stringParse = new string[] listName.Replace(" ", "") + '$';

foreach (var item in selectedCheckBoxItems)

    var val = item.Value;
    var key = item.Key;
    var idxArray = key.Split(stringParse, StringSplitOptions.None);
    var idxString = idxArray[idxArray.Length - 1];
    int idxInt;
    if (Int32.TryParse(idxString, out idxInt))
    
        cbl.Items[idxInt].Selected = true;
    

【讨论】:

【参考方案3】:

这是解析键以获取所选索引的另一种方法。它还使用UniqueID 属性来查找相关键。

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                            where key.Contains(cblAnimalType.UniqueID)
                            select new  Value = Request.Form.Get(key), Key = key ;

foreach (var item in selectedCheckBoxItems)

    var val = item.Value;
    string indexToken = item.Key.Replace(cblAnimalType.UniqueID, "");
    int index = int.Parse(Regex.Replace(indexToken, @"[^\d]", ""));
    ...

【讨论】:

我希望摆脱解析来获取索引。但是,我知道如果这是唯一的方法,那将是我需要做的。这种解析方法似乎比我想出的更好。【参考方案4】:

我意识到这与之前的回复非常接近,所以我不确定它是否添加了任何内容,但它更简洁一些,所以我会添加它。在Request.Form.AllKeys 中,Key 是复选框的 html 名称。复选框的 html 名称包含索引。我只是将您的 linq 查询更改为仅选择“打开”的项目,然后返回键列表。之后,您只需解析键即可获取索引。

var selectedCheckBoxItems = from key in Request.Form.AllKeys
                            where key.Contains(cbl.ID) && Request.Form.Get(key) == "on"
                            select key;

foreach (var item in selectedCheckBoxItems)

     var index = 0;
     if (int.TryParse(item.Substring(item.LastIndexOf("$") + 1), out index))
     
         //do what you will
      

此外,在这种情况下,字符串解析非常安全,因为字段名称是由框架以非常具体和公式化的方式生成的。他们曾经不同的几率即使不是零也接近。

【讨论】:

以上是关于使用 Request.Form 确定在 CheckBoxList 中选择了哪些项目的主要内容,如果未能解决你的问题,请参考以下文章

处理“潜在危险的 Request.Form 值...”

Request[" "]Request.Form[" "]Request.QueryString[" "] 的使用及区别

Request.Params 和 Request.Form 啥时候不同?

使用 ajax 传递数据并使用 Request.Form[""] 读取数据

无法使用来自axios请求的request.form在flask api中获取请求正文[重复]

request.form()和request()的区别?