ViewState的一些疑问
小弟不才,属于初学者,在进行项目练习时,遇到ViewState问题,需要使用repeater控件进行绑定后台数据,在页面上显示,这就造成了页面上的ViewState字段的长度进行大量增长,造成了页面加载速度的降低,本人对ViewState的了解仅涉猎于表面理解,知道它是记录一些值,帮主页面记忆一些值,通过对它的解码,发现全是后台绑定的数据,我的目前疑问是,是把整个页面的ViewState禁用还是禁用数据控件的? --------------------编程问答-------------------- 看情况,一种是启用viewstate,会增加页面的代码;另一种是禁用Repeater的viewstate,但需要每次请求页面时都执行查询数据库并绑定Repeater,可以专门写个方法。如果页面上没有会发生“回发”的按钮、超链接等,可以禁用页面级的viewstate、否则只禁用控件级的即可。 --------------------编程问答--------------------+1 --------------------编程问答-------------------- 你的网络下载速度是多少?__ViewState多出来的字节占用了多少下载速度?
如果确实很大,以至于页面提交时会出现解析错误,那么可以使用这个类替换为你的Page的父类:
using System;它是使用本地的缓存和硬盘,来取代远程客户端。 --------------------编程问答-------------------- 其实很多人对于asp.net的应用并没有分别看清。假设你想模仿各大网站的那种去写网页,那么你的页面根本不应该有任何回发设计,凡是需要用户体验好一点的信息提交应该使用ajax,凡是根本不用顾用户体验的信息提交全都像asp那样通过<form />提交到另外一个页面(刷新整个页面)。
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Web.UI;
public class VPage : Page
{
static private DirectoryInfo _Dir;
private static DirectoryInfo Dir
{
get
{
if (_Dir == null)
{
_Dir = new DirectoryInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data"));
if (!_Dir.Exists)
_Dir.Create();
_Dir = new DirectoryInfo(Path.Combine(_Dir.FullName, "ViewState"));
if (!_Dir.Exists)
_Dir.Create();
}
return _Dir;
}
}
protected override object LoadPageStateFromPersistenceMedium()
{
PageStatePersister ps = this.PageStatePersister;
ps.Load();
if (ps.ControlState != null)
ps.ControlState = 反序列化对象((string)ps.ControlState);
if (ps.ViewState != null)
ps.ViewState = 反序列化对象((string)ps.ViewState);
return new Pair(ps.ControlState, ps.ViewState);
}
protected override void SavePageStateToPersistenceMedium(object state)
{
PageStatePersister ps = this.PageStatePersister;
if (state is Pair)
{
ps.ControlState = ((Pair)state).First;
ps.ViewState = ((Pair)state).Second;
}
else
ps.ViewState = state;
if (ps.ControlState != null)
ps.ControlState = 序列化对象(ps.ControlState);
if (ps.ViewState != null)
ps.ViewState = 序列化对象(ps.ViewState);
ps.Save();
}
private object 反序列化对象(string stateID)
{
if (stateID == null)
return null;
object state = Cache[stateID];
if (state == null)
using (var stream = File.OpenRead(Path.Combine(Dir.FullName, stateID)))
state = new BinaryFormatter().Deserialize(stream);
else
Cache.Remove(stateID);
return state;
}
private string 序列化对象(object obj)
{
string stateID = Guid.NewGuid().ToString("N");
Cache.Insert(stateID, obj, null, DateTime.Now.AddMinutes(5), System.Web.Caching.Cache.NoSlidingExpiration);
using (var stream = File.Create(Path.Combine(Dir.FullName, stateID)))
new BinaryFormatter().Serialize(stream, obj);
return stateID;
}
static VPage()
{
ThreadPool.QueueUserWorkItem(h =>
{
var et = DateTime.Now.AddMinutes(-30);
Dir.GetFiles()
.Where(f => f.LastAccessTime < et)
.ToList()
.ForEach(f =>
{
try
{
f.Delete();
}
catch { }
});
});
}
}
但是要注意,这可不是在开发企业应用程序。
对于企业应用程序,传统的asp.net的那种仿 winform 的状态机制,过去曾经是非常适合的。但是这几年已经完全跟不上 ajax 的潮流了。除非你使用silverlight这类比较高级的平台,使用jquery或者asp要想做出一个用户体验比较好的、有着非常丰富的界面布局和很多内容的“大”画面的web应用,是非常困难的。这样的页面根本不用在页面跳来跳去,而是无刷新地让用户“沉浸”在一个页面上一段时间就能干完持续一个小时以上的业务操作。 --------------------编程问答-------------------- 学习 --------------------编程问答-------------------- 首先感谢以上回复的朋友,AJAX目前还没有学习到,项目实战结束了才会进行学习,所以就要在不实用AJAX的情况下进行设计了,因为页面上有些新闻和产品都需要到数据库进行读取连接和内容,有专门的SQLHelper类,使用的是存储过程,目前的小疑问得到了解决,但是又有了点新的需求,怎么更好的去理解VIEWSTATE和更好的利用它去干一些漂亮的事情, --------------------编程问答-------------------- 学习了…………
补充:.NET技术 , ASP.NET