ViewState用来保存往返页面和控制值,从而可以使新请求的页面恢复为提交页面的状态。
ViewState以加密方式保存在隐藏字段__ViewState__中
但是我有很大的疑问:
1>为什么TextBox的Color,MaxLength等属性也保存在ViewState中?(反编译可以看到)
2>TextBox的Text值本来就会回传到服务器,还为什么要保存在ViewState中?(类似有Select的value等)
3>由于1>2>,ViewSate到底有什么用?
200分求答案。可以比较具体的说明ViewState的用法的话,可以加分。代码只要说明问题即可,不要复制和粘贴一大堆。
网友回复:mark
网友回复:先回答一个问题
(1)Color,MaxLength等属性为什么要保存在ViewState中?
C# code
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
//自定义控件
public class SampleControl : WebControl{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get;set;
}
#endregion
protected override void Render(HtmlTextWriter writer)
{
writer.Write(Text);
}
}
}
C# code
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
protected void Button2_Click(object sender, EventArgs e)
{
this.SampleControl1.Text = "btn1";
}
protected void Button3_Click(object sender, EventArgs e)
{
}
假如你先点Button2,页面展示btn1。然后你再你认为你点Button3的时候,页面上展示的控件会显示什么呢?ViewState的作用就是用来保持这个btn1的。当前没有使用ViewState保持Text的值,所以页面不会保持btn1
网友回复:可能我理解的比较浅显:
ViewState用来保存页面状态,就是说提交之后我们还可以看到文本框里面的内容就是ViewState保存的功劳。
ViewState只维护当前页面的状态,不同页面之间不能共享,Session可以。
ViewState你可以理解为一个隐藏控件。
网友回复:state嘛,当然是用来保存状态的。 主要配合postback功能,有些控件使用自动post功能,其他控件在post后在显示时要保留之前的状态(显示的数据、用户输入的数据)就是靠viewstate了。
你也可以编程使用viewstate, post前放些数据,post后读取。page,服务器端控件都有自己的viewstate.
网友回复:第二个问题:
TextBox的Text值的确保存在ViewState中。但是也同时保存在“控件状态”中。
如下:
C# code
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
base.ValidateEvent(postDataKey);
string text = this.Text;
string str2 = postCollection[postDataKey];
if (!this.ReadOnly && !text.Equals(str2, StringComparison.Ordinal))
{
this.Text = str2;
return true;
}
return false;
}
网友回复:假如Color,MaxLength等不保存在控件状态中的话,假如服务器端对其进行了更改,这个更改是无法保存的。虽然当前的页面对象的状态是正确的,但是再次post的时候,页面对象的状态会丢失。
网友回复:你也可以禁用viewstate,这样可以减少交互数据量,但是你要自己处理所有传递参数了。
网友回复:Web窗体是无状态的。
要保留某些状态必须用到ASP.NET的内置对象。
在ASP.NET页面间传递数据的方式有几种:
1.传递数据给页面本身
使用ViewState对象。
2.传递给当前页面链接到的另一页面
使用Request.QueryString
3.传递给没有直接关联的页面
使用Session、Cookie或全局变量。
如上,ViewState用来给页面本身传递数据用。比如我们有一个变量,值为:100,然后页面放一个按钮,每点一次给这个变量加1,然后显示到一个TextBox中,通常应该是这样的代码:
private int id;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
id = 100;
}
}
protected void Button1_Click(object sender, EventArgs e)
{
id ;
TextBox1.Text = id.ToString();
}
但是,实际运行一下会发现结果不是我们预想的。这是因为:当页面提交或刷新后,由于Web页面的无状态性,这个变量的值会消失,因此通常把它保存到ViewState中,在刷新后从ViewState中取回该值。改用下面的代码:
private int id;
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["id"]==null)
{
id = 100;
ViewState["id"] = id;
}
else
{
id =(int) ViewState["id"];
}
}
protected void Button1_Click(object sender, EventArgs e)
{
id ;
TextBox1.Text = id.ToString();
ViewState["id"] = id;
}
就可以得到我们想要的结果。
ViewState对象
在页面回传间通信,ASP中一般利用窗体的属性和 session 来存放数据,在 ASP.NET 中也可以使用 ViewState 对象来做同样的处理。
在ViewState存放数据:
ViewState[key]= value;
或
ViewState.Add(key,value);
取出数据:
TempStr =ViewState[key];
key不存在时返回空。
不能通过ViewState对象来访问控件的值。
动态建立控件的ViewState:
当需要动态地建立一个服务器控件,如下建立了一个 RadioButton 控件并加入到窗体控件集合中:
RadioButton rb = new RadioButton();
Page.Controls[1].Controls.Add(pc);
上面的代码增加一个控件到控件集合末,同样也可以插入到已有控件中的任何位置。
RadioButton rb = new RadioButton();
Page.Controls[1].Controls.AddAt(1,pc);
通常,这些动态生成的控件的状态也需要生成到 ViewState 中去,但这个功能并没有完全实现,特别是生成的控件插入到已有的控件中时。
当动态生成控件和已有控件并存时 ViewState 的结果是不可预料的。在页面回传时,首先非动态生成的控件在ASPX页中被生成,并在 Page_Init 和 Page_Load 事件中读取 ViewState。当页面的控件读取 ViewState 的值时,那些动态生成的控件却还没有被生成,所以当动态生成的控件被
生成时,页面就会省略掉ViewState或者以剩下或许错误的 ViewState 来填充控件。
所以,当需要插一个动态生成的控件到已有控件中去时,最好把这个控件的 ViewState 通过EnableViewState禁止掉。
提醒:
1. 当存在页面回传时,不需要维持控件的值就要把 ViewState 禁止。
2. ViewState的索引是大小写敏感的。
3. ViewState不是跨页面的。
4. 为了能包存在 ViewState 中,对象必须是可流化或者定义了 TypeConverter。
5. 控件 TextBox 的 TextMode 属性设置为 Password时,它的状态将不会被保存在 ViewState 中,这应该是出于安全性的考虑。
6. 在页面没有回传 或 重定向 或 在回传中转到(transfer)其他页面时不要使用 ViewState。
7. 在动态建立控件时要小心它的 ViewState。
8. 当禁止一个程序的 ViewState 时,这个程序的所有页面的 ViewState 也被禁止了。
9. 只有当页面回传自身时ViewState 才是持续的。