比如说
DataTable dt1 = new DataTable();
//给dt赋值
//....//ViewState中保存
ViewState["TableData"] = dt1;dt是一个实例化的对象 引用类型 我的理解是在堆栈中开辟了个空间 里面存放了指向托管堆dt数据的地址
假如用例外一个实例dt2 = dt1;
那肯定是dt只把堆栈中的地址给了dt2,所以dt2的改变dt1也随之改变
ViewState["TableData"] = dt1;
这句话ViewState["TableData"]中存的是地址呢还是一个真正的有值的对象??
请大虾们看看 我感觉应是地址吧
DataTable dt1 = new DataTable();
//给dt赋值
//....//ViewState中保存
ViewState["TableData"] = dt1;dt是一个实例化的对象 引用类型 我的理解是在堆栈中开辟了个空间 里面存放了指向托管堆dt数据的地址
假如用例外一个实例dt2 = dt1;
那肯定是dt只把堆栈中的地址给了dt2,所以dt2的改变dt1也随之改变
ViewState["TableData"] = dt1;
这句话ViewState["TableData"]中存的是地址呢还是一个真正的有值的对象??
请大虾们看看 我感觉应是地址吧
value="/" />
ViewState在客户端的保存形式,保存在一个ID为__VIEWSTATE的Hidden中,它的Value是使用Base64编码后的字符串。这个字符串实际上是一个对象序列化之后的结果。这个对象保存了整个页面的控件树的ViewState。可以使用一些工具将这个字符串进行解码查看其内容,比如ViewStateDecoder,ViewStateAnalyzer。
确实,如果在A页面中
DataTable dt1 = new DataTable()//给dt赋值
//....//ViewState中保存
ViewState["TableData"] = dt1;
那么在B页面中可以使用ViewState["TableData"],但是很明显,此时DataTable dt1已经销毁了~
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 />");
}
}
}
}
我做了下测试,赞同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>
ViewState["TableData"] = dt 这里存的是引用(其实就是地址)2. 当呈现页面,到 input hidden 的时候,就要发生“序列化”的过程,将这个引用指向的对象的实际数据,按这个的对象向本身的序列化规则序列化,并以 base64(默认)编码3. 当提交页面,发生与 2 相反的过程4. 其实,在.NET中,只要是 引用类型,默认传递的就是 “引用本身”,不管是方法参数还是赋值
Jinglecat序列化过程是什么呢?
还有你说的将这个引用指向的对象的实际数据 input hidden 里面的值到底是引用指针还是对象的实际数据??
还有第3步这个过程能详细说明下不
ViewState就会序列化,序列话就是将对象状态转换为可保持或传输的格式的过程,简单点就将对象转换成字符串(当然也有其他形式了)。
等你使用ViewState["TableData"]的时候,然后进行反序列化,就会获得dt的对象。input hidden的值保存的是序列化的对象,所以肯定是对象的实际数据。而不是引用指针。