ASP.Net学习笔记013--ViewState初探2

来源:互联网 发布:vs 变量已被优化掉 编辑:程序博客网 时间:2024/06/01 10:06
ASP.Net学习笔记013--ViewState初探2
上课讲的viewstate,由于需要跟后台服务器进行传值,需要封装很多隐藏列,比如100条数据,就会有100个viewstate
如果用在一些小的控件上的话,性能还行:如果用在一些大控件,比如listview,从数据库中取很多数据的时候,
会把数据放到viewstate里,这样滚动条基本上滚的很慢了.
datagridview和listview会默认的把取到的数据,放到viewstate中,就会产生很多用不到的html代码,会拖慢页面加载
---------------------------------------------------------------------------------------------
互联网项目网页中需要部分禁用viewstate,提高加载速度
互联网网站:
禁用viewstate只是把尺寸减小,并不是完全禁用viewstate,要想不用viewstate,只能不是用服务端控件
不使用form,使用原生态的get来实现
-------------------------------------------------------------------------------------------------------
一般网页中:
datagridview和listview,和repeter这种控件需要禁用,普通的控件不用禁用,比如上节课写的例子中的用法:
Repeater 控件用于显示重复的项目列表,这些项目被限制在该控件。
这里说一个学习网站:
http://www.w3school.com.cn/aspnet/aspnet_datalist.asp
--------------------------------------------------------------
看看如何禁用viewstate
1.禁用单个控件的viewstate,可以选中某个控件,然后设置:EnableViewState属性,设置为False就可以了
2.设置整个页面的viewstate:
宽度自增.aspx
---------------------------------------------------------
可以在:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="宽度自增.aspx.cs" Inherits="宽度自增" %>这句话中加入:
<%@ Page Language="C#" EnableViewState="False" AutoEventWireup="true" CodeFile="宽度自增.aspx.cs" 
Inherits="宽度自增" %>
EnableViewState="False"这样的一句,来禁用整个页面的viewstate
--------------------------------------------------------------------------------
利用:EnableViewState="False"禁用viewstate的值,之后访问宽度自增.aspx


<%@ Page Language="C#" EnableViewState="False" AutoEventWireup="true" CodeFile="宽度自增.aspx.cs" Inherits="宽度自增" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        #form1
        {
            height: 70px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
    <div>    <asp:TextBox ID="TextBox1" runat="server">0</asp:TextBox>
        <asp:Button ID="Button2" runat="server" onclick="Button2_Click" Text="Button" />
    </div>


    </form>
</body>
</html>
-------------------------------------------------
这个时候,点击label旁边的按钮的时候发现服务器报错:
“/WebSiteTest”应用程序中的服务器错误。


输入字符串的格式不正确。


说明: 执行当前 Web 请求期间,出现未经处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 


异常详细信息: System.FormatException: 输入字符串的格式不正确。


源错误: 




行 17:     protected void Button1_Click(object sender, EventArgs e)
行 18:     {//取到label的值,然后自增后赋值回去
行 19:         int i = Convert.ToInt32(Label1.Text);
行 20:             i++;
行 21:             Label1.Text = i.ToString();


源文件: g:\NET学习\workspace\WebSiteTest\宽度自增.aspx.cs    行: 19 


堆栈跟踪: 
[FormatException: 输入字符串的格式不正确。]
   System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal) +11013491
   System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info) +145
   System.Convert.ToInt32(String value) +43
   宽度自增.Button1_Click(Object sender, EventArgs e) in g:\NET学习\workspace\WebSiteTest\宽度自增.aspx.cs:19
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +9628442
   System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +103
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +35
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1724


版本信息: Microsoft .NET Framework 版本:4.0.30319; ASP.NET 版本:4.0.30319.34280
-------------------------------------------------------------------------
报错的位置就是:
 int i = Convert.ToInt32(Label1.Text);
 这里取不到:Label1.Text的值了
 ---------------------------------------------------------------------------------
可以改一下:
宽度自增.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;


public partial class 宽度自增 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!IsPostBack ){//直接进入的时候设置为0
            Label1.Text = "0";
            //IsPostBack这里的IsPostBack就是,以前讲的通过隐藏字段传递的
        }
    }
    protected void Button1_Click(object sender, EventArgs e)
    {//取到label的值,然后自增后赋值回去


    //---------------------修改的这个地方,加了这样的两句话----------------
        Response.Write(Label1.Text .Length );
        return;
//---------------------修改的这个地方,加了这样的两句话----------------


        int i = Convert.ToInt32(Label1.Text);
            i++;
            Label1.Text = i.ToString();
    }


    protected void Button2_Click(object sender, EventArgs e)
    {
        //值自增
        int i = Convert.ToInt32(TextBox1.Text);
        i++;
        TextBox1.Text = i.ToString();
        //宽度自增
        //TextBox1 .Width.Type  = UnitType.Pixel;
        //通过上面这个代码可以看到:
        //这个宽度的单位是unit
        TextBox1.Width = new Unit(TextBox1 .Width .Value +10);
        //每次都增加十个像素
    }
}


访问地址:
http://localhost:53627/WebSiteTest/%E5%AE%BD%E5%BA%A6%E8%87%AA%E5%A2%9E.aspx
%E5%AE%BD%E5%BA%A6%E8%87%AA%E5%A2%9E.aspx由于编码问题显示成了UT8编码的格式
可以看到
点击按钮的时候,打印出Label1.Text .Length的长度就返回了,但是这个时候按第二个text框旁边的
按钮的时候,是没有问题的,因为input表单类型的控件不需要viewstate就可以提交数据
-------------------------------------------------------------------------
一般就是禁用listview等的viewstate就可以
---------------------------------------------------------------------------------
内网系统,互联网后台可以用viewstate
--------------------------------------------------
讨论:为什么
label.text这里用.就可以.出来
内部从viewstate取的,解析viewstate后得出的结果
--------------------------------------------------
这里可以用.NET Reflector来反编译Label这个类,可以得到:
public virtual string get_Text(){
object obj2 = this.ViewState["Text"];
....
}
可以看到底层就是从viewstate中获取的,viewstate先存储为xml然后编码成html显示的内容
--------------------------------------------------
出现上面的问题的根本原因就是:
http是无状态的协议,不会记得上次和网页发生了什么,如果要知道上一次的状态
一个方法是在对浏览器相应结束之前将状态信息保存到页面表单中,下次页面再向
服务器发出请求的时候带上这些状态信息,这样服务器就能根据这些状态信息还原
上次的状态了,类似于看病的病历本
----------------------------------------
状态信息保存在隐藏字段中的缺点:
加大网站的流量,降低访问速度,机密数据放到表单中会有数据欺骗等安全性问题
-----------------------------------------------------------------------
就像电影:
女孩[浏览器]生病了只能记住24小时的内容,
男孩[服务器]就拿相机把女孩[浏览器]每天的活动都录下来,第二天再给她看
但这里也有问题:
男孩如果骗女孩的话,女孩也会信以为真
0 0
原创粉丝点击