比如说
DataTable dt1 = new DataTable();
//给dt赋值
//....//ViewState中保存
ViewState["TableData"] = dt1;dt是一个实例化的对象 引用类型 我的理解是在堆栈中开辟了个空间  里面存放了指向托管堆dt数据的地址
假如用例外一个实例dt2 = dt1;
那肯定是dt只把堆栈中的地址给了dt2,所以dt2的改变dt1也随之改变
ViewState["TableData"] = dt1;
这句话ViewState["TableData"]中存的是地址呢还是一个真正的有值的对象??
请大虾们看看  我感觉应是地址吧

解决方案 »

  1.   

    ViewState["TableData"]此时也就是一个引用。
      

  2.   

    ViewState["TableData"] 传递的是对象了,在页面向服务器端传递的时候是序列化在页面的传递的。可以在页面右键查看源文件就可以看到
      

  3.   

    input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" 
    value="/" />
    ViewState在客户端的保存形式,保存在一个ID为__VIEWSTATE的Hidden中,它的Value是使用Base64编码后的字符串。这个字符串实际上是一个对象序列化之后的结果。这个对象保存了整个页面的控件树的ViewState。可以使用一些工具将这个字符串进行解码查看其内容,比如ViewStateDecoder,ViewStateAnalyzer。
      

  4.   

    Page对客户端请求进行处理,在处理的过程中先是将客户端提交的_VIEWSTATE反序列化为对象,调用Control的相关方法给所有的控件装载数据,这些数据是上次请求结束后控件的状态数据。在请求结束之前调用Control的相关方法得到所有控件的被修改过的状态数据,之后Page将其进行序列化,并返回给客户端。在Control中又具体调用StateBag类的方法完成状态数据的加载和保存。
      

  5.   

    呵呵,学习了,看来俺理解的还不够深刻~
    确实,如果在A页面中
    DataTable dt1 = new DataTable()//给dt赋值
    //....//ViewState中保存
    ViewState["TableData"] = dt1;
    那么在B页面中可以使用ViewState["TableData"],但是很明显,此时DataTable dt1已经销毁了~
      

  6.   

    ViewState  可以存DataTable 类型的吗?   他只能存值呀不能存对象吧!
      

  7.   

    保存到页面中,应该是对象。using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;namespace AspxTest
    {
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {        }        protected void BWrite_Click(object sender, EventArgs e)
            {
                string[] stringArray = new string[] { "AA", "BB" };
                this.ViewState["StringArray"] = stringArray;
            }        //点击“BWrite”,写入后。重启调试用的WEB服务器,再点击“BRead”,输出还是AA和BB        protected void BRead_Click(object sender, EventArgs e)
            {
                string[] stringArray = (string[])this.ViewState["StringArray"];
                foreach (string item in stringArray)
                {
                    Response.Write(item + "<br />");
                }
            }
        }
    }
      

  8.   

    非常感谢大家的回答,有的人说是地址有的人说是存的对象值
    我做了下测试,赞同wuyq11的看法,也许是我没说清楚,整理下应该是有2个步骤吧
    程序运行处理时候的ViewState
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            
            If Not IsPostBack Then
                Dim arr1 As ArrayList = New ArrayList()
                arr1.Add("Apple")
                ViewState("obj") = arr1
                '此时的ViewState("obj")中存的是arr1的地址
                'arr1长度为1,所以ViewState("obj")的长度为1
                arr1.Add("banana")
                '追加一个项目后arr1长度为2
                '因为ViewState("obj")中存的是arr1的地址,所以ViewState("obj")的长度也是2
            Else
                '页面提交后,如在客户端的保存形式,wuyq11所说,在客户端保存在一个ID为__VIEWSTATE的Hidden中
                '这个字符串实际上是一个对象序列化之后的结果。这个对象保存了整个页面的控件树的ViewState。
                '此时的ViewState("obj")的内容是客户端保存的值
                Dim arr2 As ArrayList = CType(ViewState("obj"), ArrayList)
            End If
    End Sub我的理解是Not IsPostBack中的ViewState("obj")在页面生成显示后,把值给存放在客户端,之后ViewState("obj")对象也就被扔了。
    提交后,用ViewState("obj")提取的是页面客户端的真正的值,和之前被扔的ViewState("obj")对象毫无关系,不知道这么理解对不对,呵呵<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTkwNjc4NTIwMQ8WAh4Db2JqFgIFBUFwcGxlBQZiYW5hbmFkZHNiUrV2u+KJB7I2r+5lkthXA1GJ" />
    下面是用ViewStateDecoder工具察看的结果
    Tree Display显示方式
    -viewstate
      -Pair
        -Pair
          -String
            -1906785201
          -Pair
            -ArrayList
              -IndexedString
                -obj
              -ArrayList
                -String
                  -Apple
                -String
                  banana
    Raw XML显示方式
    <?xml version="1.0" encoding="utf-16"?>
    <viewstate>
      <Pair>
        <Pair>
          <String>1906785201</String>
          <Pair>
            <ArrayList>
              <IndexedString>obj</IndexedString>
              <ArrayList>
                <String>Apple</String>
                <String>banana</String>
              </ArrayList>
            </ArrayList>
          </Pair>
        </Pair>
      </Pair>
    </viewstate>
      

  9.   

    ViewState只是本页面内用来保存对象的Object变量
      

  10.   

    其实你只要去看看HTTP协议及序列化和反序列化的知识就明白了...ViewState保存的是对象序列化后的字符串,而HTTP是无连接协议两次请求的页面对客户端来说几乎没有任何关联...地址一说毫无根据...另外在.NET中除了与API的交互之外没有“地址”的概念...引用是封装过的指针,与C/C++中的指针都没有可比性,更不要和C/C++中的内存地址混淆...
      

  11.   

    还有...不建议将DataSet、DataTable或类似的大对象保存在ViewState中,ViewState中的对象都要序列化后写入客户端HTML并在PostBack时反序列化,对带宽、性能都有影响...ViewState只应该保存轻量级对象...
      

  12.   

    vrhero  关于你说的地址概念,.net和c/c++ 能详细的讲解下不  有资料看也可以
      

  13.   

    1. 内存中
    ViewState["TableData"] = dt 这里存的是引用(其实就是地址)2. 当呈现页面,到 input hidden 的时候,就要发生“序列化”的过程,将这个引用指向的对象的实际数据,按这个的对象向本身的序列化规则序列化,并以 base64(默认)编码3. 当提交页面,发生与 2 相反的过程4. 其实,在.NET中,只要是 引用类型,默认传递的就是 “引用本身”,不管是方法参数还是赋值
      

  14.   


    Jinglecat序列化过程是什么呢?
    还有你说的将这个引用指向的对象的实际数据 input hidden 里面的值到底是引用指针还是对象的实际数据??
    还有第3步这个过程能详细说明下不
      

  15.   

    ViewState["TableData"] = dt;这里是引用的,当页面加载完毕之后
    ViewState就会序列化,序列话就是将对象状态转换为可保持或传输的格式的过程,简单点就将对象转换成字符串(当然也有其他形式了)。
    等你使用ViewState["TableData"]的时候,然后进行反序列化,就会获得dt的对象。input hidden的值保存的是序列化的对象,所以肯定是对象的实际数据。而不是引用指针。