使用 Request.Form 确定在 CheckBoxList 中选择了哪些项目
Determining which items are selected in CheckBoxList using Request.Form
使用问题 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"。
我需要能够通过索引或其他方法确定哪个项目是 "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 中拉出来,但看起来如果该设置可以安全删除,则可以从代码隐藏访问复选框列表值。
我想到了一种方法,将密钥添加到结果中。由于获取索引所需的字符串解析,我对这种方法并不完全满意。也许其他人有更好的方法?
大意是在结果中加上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;
}
}
当您将 Database
中的 checkboxList
与 OptionId
字段绑定时,您可以检查哪些 checkboxes
被 select 编辑并将它们的值存储在 List<int>
假设它们的值为 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()));
}
然后当您 populate
checkboxlist
时,您可以通过 value
和 select 找到项目
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" />
这是另一种解析键以获取所选索引的方法。它还使用 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]", ""));
...
}
我意识到这与之前的回复非常接近,所以我不确定它是否添加了任何内容,但它更简洁一些,所以我会添加它。在Request.Form.AllKeys
中,Key
是复选框的html名称。复选框的 html 名称包含索引。我只想将您的 linq 查询更改为仅 select "on" 的项目,然后 return 键列表。之后,您只需解析键即可获取索引。
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
}
}
此外,此实例中的字符串解析非常安全,因为字段名称是由框架以非常具体和公式化的方式生成的。他们不一样的几率即使不是零也接近于零。
使用问题 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"。
我需要能够通过索引或其他方法确定哪个项目是 "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 中拉出来,但看起来如果该设置可以安全删除,则可以从代码隐藏访问复选框列表值。
我想到了一种方法,将密钥添加到结果中。由于获取索引所需的字符串解析,我对这种方法并不完全满意。也许其他人有更好的方法?
大意是在结果中加上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;
}
}
当您将 Database
中的 checkboxList
与 OptionId
字段绑定时,您可以检查哪些 checkboxes
被 select 编辑并将它们的值存储在 List<int>
假设它们的值为 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()));
}
然后当您 populate
checkboxlist
时,您可以通过 value
和 select 找到项目
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" />
这是另一种解析键以获取所选索引的方法。它还使用 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]", ""));
...
}
我意识到这与之前的回复非常接近,所以我不确定它是否添加了任何内容,但它更简洁一些,所以我会添加它。在Request.Form.AllKeys
中,Key
是复选框的html名称。复选框的 html 名称包含索引。我只想将您的 linq 查询更改为仅 select "on" 的项目,然后 return 键列表。之后,您只需解析键即可获取索引。
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
}
}
此外,此实例中的字符串解析非常安全,因为字段名称是由框架以非常具体和公式化的方式生成的。他们不一样的几率即使不是零也接近于零。