您的位置:首页 > 编程语言 > ASP

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

2017-04-24 19:58 411 查看
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小时的内容,

男孩[服务器]就拿相机把女孩[浏览器]每天的活动都录下来,第二天再给她看

但这里也有问题:

男孩如果骗女孩的话,女孩也会信以为真
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: