使用的知识点
- 跨页面遍历动态控件,脱离session和cookie
- 遍历页面控件对控件进行初始化
- 跨页面传值(Server.Transfer(url))
2018/10/10
问题和解决
1.遍历一个二维字符串数组(更像一个axis)
//定义一个二维字符串数组
string[, ] s = {{"a","1","2"},{"b", "1", "2"}}
//遍历
int rank = s.Rank; //得到维度,维度不确定情况下
if(rank == 2) //可不要
{
for(int i = 0; i< s.GetLength(0); i++) //得到行数
{
for (int j = 0; j< s.GetLength(1); j++) //得到列数
{
Console.WriteLine(s[i, j]);
}
}
}
else if(rank == ...)
2.跨页面调用动态控件
- a.aspx
protected void Page_Load(object sender, EventArgs e) { //if (!IsPostBack) 切记!动态生成控件事件不可包入这里面,否则无法实现跨页面遍历动态控件 for(int i = 0; i < 10; i++) {//生成是个label Label label = new Label(); label.ID = i;//为方便遍历效率,循环定义id label.Text = i; panel.Controls.Add(label); } } //点按钮执行Server.Transfer("b.aspx", true);
- b.aspx
protected void Page_Load(object sender, EventArgs e) { for(int i = 0; i < 10; i++) {//遍历上一个页面的生成的控件的值 Label label = (Label)this.PreviousPage.FindControl(i);//以id进行控件查找 Response.Write(label.Text);//检验值 } }
3.清空动态生成的控件的值(清空按钮)
先给代码吧,问题再讲。
这也是另一种遍历控件的方法,通过控件类型来查找并做处理。
public void clear(Control parContainer)
{
for (int index = 0; index < parContainer.Controls.Count; index++)
{ //使用parContainer.Controls遍历所有控件
if (parContainer.Controls[index].HasControls())
{
clear(parContainer.Controls[index]);
}
if (parContainer.Controls[index].GetType().Name.Equals("RadioButtonList"))
{
RadioButtonList rblist = (RadioButtonList)(parContainer.Controls[index]);
foreach (ListItem item in rblist.Items)
item.Selected = false;
}
if (parContainer.Controls[index].GetType().Name.Equals("CheckBoxList"))
{
CheckBoxList cblist = (CheckBoxList)(parContainer.Controls[index]);
foreach (ListItem item in cblist.Items)
item.Selected = false;
}
}
}
之后在button事件里来调用该函数来清空选择,这时候你会发现,整个页面被刷新了一次,如果你是随机产生控件的值,那么,你会发现,你不仅达到了清空效果,还达到了刷新页面重新随机效果?!
4.针对上一点最后产生的问题进行解决
- 产生的原因:首先,你用客户端控件加上js或jQuery清空页面控件的值,例如,
<input type="button".../>
你点击后,页面并不会刷新,但服务器控件(含runat=“server”)就会出现这个问题,及时你将它的type改成button依旧会刷新页面。因为默认为submit,将form表单进行提交。 - 解决方法:在a.aspx.cs中定义一个全局对象
static Question question = new Question();
创建一个类,里面有set、get方法,来存放你随机产生的值,之后对随机控件进行赋值时,使用question.get_question();
如下:if (!IsPostBack)//注意!存放随机产生的值时,一定要进行防刷新处理! { //将随机组到的题存入静态类中存放 question.set_question('你随机生成的一组数据,类型自定'); } for(int i = 0; i < 10; i++)//不进行防刷新处理同问题2 {//生成是个label Label label = new Label(); label.ID = i;//为方便遍历效率,循环定义id label.Text = question.get_question();//如果你存放的是数组或是其他数据,需要先处理后赋值 panel.Controls.Add(label); }
5.跨页面传值(Server.Transfer(“b.aspx”, true))
跨页面传值的方法很多,一搜全是,我这里只讲一种。
我遇到的问题是:我随机产生了一套问题,将答案存在了这个页面的全局变量public string[] answer
中,想将该数组传到第二个页面,同时得到用户的回答进行改卷,不使用session、cookie怎样得到?
-
方法一:Context.Handler
a front_page = (a)Context.Handler;//取得a页面的Handler,间接获得值 string[] answer = front_page.answer;
- 问题一:你会发现,取不出该值,why?因为你跳转后,页面会先刷新一遍,此时answer数组便清空了!2333
- 解决一:仿照问题4处理为static
public static string[] answer
产生的连锁问题:虽然对按钮刷新页面进行了处理,但是如果多用户同时访问(就好像你开两个浏览器一起操作),你就会发现结果会出现错误,因为static是静态,一旦一个用户进入页面便固定不再改变,而你的问题和对应的答案是随机的,那么,答案只能是第一套题的答案
-
方法二:HiddenField隐藏控件
step 1: a.aspx中加上该控件<asp:HiddenField ID="answer" runat="server" />
step 2:a.aspx.cs中将answer赋给该控件
answer.value = myanswer; //假设你的myanswer数据类型是string
step 3:b.aspx取该控件的值
answer = Request.Form["answer"];
产生的连锁问题:你打开页面源代码,你会发现问题的答案就存在里面,emm就变成看着答案做题目了。。。解决方法一的缺点,但并未根治。
6.无法解决的问题
第5点貌似解决了多用户同时访问跨页面传值问题,但仍有一个第4点产生的问题:你的问题是static的,那么,打开两个浏览器A、B进行操作,A浏览器先打开,A做好提交后,B再提交,那么会发现,后台收到的B浏览器的选择跟A浏览器的选择是一样的!
为了解决第4个问题,就一定会产生这个无法多用户同时使用的问题。
7.根治方法
综上,这个实验无法用这些知识点实现两个页面的操作
- 使用
<input .../>
+js、jquery来进行清空操作。同时,单页面进行操作,一个页面中进行组题、改卷,第二个页面只进行显示总分数。 - 使用session、cookie。
- 使用数据库,以上问题全部不存在。
2018/10/11
解决第4点问题的方法(打脸一下)
在老师的细心指导下,得到了一下这个处理方法。
使用hidden控件
在页面中放置两个hidden(根据实际情况来选择数量),例如,一个存放随机组成的问题和选择,一个存放对应的正确答案。
- 例子
a.aspx
<asp:HiddenField ID="question" runat="server" />
a.aspx.cs
public int ques;
Class1 random = new Class1();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ques = random.random_num();
hide.Value = ques.ToString();
}
Label ques_output = new Label();
ques_output.Text = "随机产生的题目为:" + hide.Value;
question.Controls.Add(ques_output);
}
protected void Button1_Click(object sender, EventArgs e)
{ //按钮无事件
;
}
- 拓展
那么,你产生的题目肯定不是一个,甚至可能是一个二维字符串数组string[, ],那么就需要做以下操作:
- 先将string[, ]转为string存放问题、选择之间用标记符分开(例如’#’),赋给hidden.value
- 取出hidden.value,将其转为string[],并遍历产生对应的动态按钮放置不同的题目和选择。
string[] question = question_choice.Value.Split('#');//以'#'为标志,将string分割为数组
优点
- 解决了多用户访问出现的问题
- 避免了使用session和cookie这些占用服务器内存和不安全的方法
缺点
- 转换次数过多,算法复杂,效率较低
- 源码中存在所有信息,会达不到刷题目的