asp.net 随机组题+跨页面显示(未用数据库)

使用的知识点

  1. 跨页面遍历动态控件,脱离session和cookie
  2. 遍历页面控件对控件进行初始化
  3. 跨页面传值(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.跨页面调用动态控件

  1. 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);
    
  2. 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.针对上一点最后产生的问题进行解决

  1. 产生的原因:首先,你用客户端控件加上js或jQuery清空页面控件的值,例如,<input type="button".../>你点击后,页面并不会刷新,但服务器控件(含runat=“server”)就会出现这个问题,及时你将它的type改成button依旧会刷新页面。因为默认为submit,将form表单进行提交。
  2. 解决方法:在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怎样得到?

  1. 方法一: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是静态,一旦一个用户进入页面便固定不再改变,而你的问题和对应的答案是随机的,那么,答案只能是第一套题的答案

  2. 方法二: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.根治方法

综上,这个实验无法用这些知识点实现两个页面的操作

  1. 使用<input .../>+js、jquery来进行清空操作。同时,单页面进行操作,一个页面中进行组题、改卷,第二个页面只进行显示总分数。
  2. 使用session、cookie。
  3. 使用数据库,以上问题全部不存在。

2018/10/11

解决第4点问题的方法(打脸一下)

在老师的细心指导下,得到了一下这个处理方法。

使用hidden控件

在页面中放置两个hidden(根据实际情况来选择数量),例如,一个存放随机组成的问题和选择,一个存放对应的正确答案。

  1. 例子

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)
        {   //按钮无事件
            ;
        }
  1. 拓展
    那么,你产生的题目肯定不是一个,甚至可能是一个二维字符串数组string[, ],那么就需要做以下操作:
  • 先将string[, ]转为string存放问题、选择之间用标记符分开(例如’#’),赋给hidden.value
  • 取出hidden.value,将其转为string[],并遍历产生对应的动态按钮放置不同的题目和选择。
string[] question = question_choice.Value.Split('#');//以'#'为标志,将string分割为数组

优点

  1. 解决了多用户访问出现的问题
  2. 避免了使用session和cookie这些占用服务器内存和不安全的方法

缺点

  1. 转换次数过多,算法复杂,效率较低
  2. 源码中存在所有信息,会达不到刷题目的
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值