这段时间,老大在看了网站后,发现viewstate所产生的一堆乱码,严重影响了我们网站http://www.xbcar.net 西部汽车网的打开速度和搜索引擎的抓取.就给我下了道铁令,三天内必须解决.这下该轮到我头大了,
例如: input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="dEV4cHJlc3Npb247UmVhZE9ubHk7PjtsPHB1Yl9uYW1lO3B1Yl9uYW1lO3B1Yl9uYW1 lO288Zj47Pj47Ozs7PjtAMDxw" /> |
我立马翻遍了所有的资料,及查遍了百度和Google。以求得到最佳解决方案。但都没有一个完整的解决方案。都写的比较零碎。但黄天不负有心人,最终还是让我找到了几种方案,并加以修改,改进。在此我要感谢这几个方案的提供者。谢谢他们的分享,在解决完我自己的问题后,有感于前几位的分享,故我也不敢独自分享,现在总结七种解决方案如下,以供大家分享,有不对的地方欢迎拍砖。现把ViewState的优化方法总结如下:
第一种解决方案(最快的一种,但是以牺牲asp.net方便性为代价的)西部汽车网
禁用viewstate。可在web.config里配置,或者页面@Page指令里加入 Enableviewstate="false" ,即可防止上面的乱码了。然后页面传值使用form或者cookies,别用session和application他们都是服务器杀手,但这种方式灵活度不高,而且微软自带的控件无法使用了,不如用JSP来做
第二种解决方案:
使用微软的MVC框架,很好用,不过个人感觉开发起来蛮麻烦的,不推荐也不抵触,觉得还不成熟这个东西
第三种解决方案:
使用ajax+web services来搞定,推荐这种方法,真正的页面代码和业务代码分离,很爽,虽然有些烦琐编码的时候,不过感觉很爽。
第四种解决方案:(改写viewSate位置,不对这种方法要每个cs代码都加入重写内容,有点烦。当然可以重写个父类可以解决。但每次都要重写,所以也会增加对服务器开销。好,不多说了,现代码贴上)
要加入using System.Text.RegularExpressions;
private static readonly Regex viewStateRegex =
new Regex("<input type=/"hidden/" name=/"__VIEWSTATE/".*/>", RegexOptions.IgnoreCase); //过滤viewstate html标记的正则表达式
private static readonly Regex endFormRegex =
new Regex(@"</form>", RegexOptions.Multiline | RegexOptions.Compiled); //过滤 </form>标记的正则表达式
//重写HTML,过滤viewstate并输出
protected override void Render(HtmlTextWriter writer)
{
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
base.Render(htmlWriter);
string html = stringWriter.ToString();
Match viewStateMatch = viewStateRegex.Match(html);
string viewStateString = viewStateMatch.Captures[0].Value;//找出ViewState的Html标记 目的把viewstate的内容放到页面FORM的最后面加快加载速度和搜索抓录
// viewStateString = "<input type=/"hidden/" name=/"__VIEWSTATE/" id=/"__VIEWSTATE/" value=/"/" />"; //仿博客园
html = html.Remove(viewStateMatch.Index, viewStateMatch.Length);//替换掉ViewState的html标记
Match endFormMath = endFormRegex.Match(html, viewStateMatch.Index);
html = html.Insert(endFormMath.Index, viewStateString);//将ViewState的Html标记插入到</form>标记之前
writer.Write(html);
}
这段代码写在你的PAGE基类里,然后看下效果就明白了,把viewstate的内容放在了最后面,这样做两个目的,第一避免VIEWSTATE过大导致页面加载速度过慢,第二避免搜索引擎访问该页面没有找到准确的信息。
第五种解决方案:(重写适配器, 这个方法就比上个方法好在不用增加多余的CPU开销)西部汽车网
该方法使用的ASP.NET控制适配器架构。
控制适配器是一个可以用来控制所产生的HTML控制它适应的类。由于页面类,是一种负责任的渲染视图状态隐藏字段( Page.BeginFormRender调用Page.RenderViewStateFields ),适配器的网页是必要的。然而,视图状态隐藏字段在ASP.NET基础架构中起着关键作用和难以修改相关的HTML 。
一个PageAdapter有一个方法叫做GetStatePersister()返回的对象继承于PageStatePersister 。当加载和保存视图状态的时候调用PageStatePersister。这里有2个类是从PageStatePersister : HiddenFieldPageStatePersister和SessionPageStatePersister继承来的。第一种是默认情况下,存储视图状态中的隐藏字段名为__VIEWSTATE 。第二个存储视图状态在session中。因此,我们可以很容易地创建一个自定义PageStatePersister来控制视图状态加载和保存过程。最大的问题是如何在form标记关闭之前建立隐藏的视图状态,同时以完全透明的解决办法。经过一些尝试我想出了一个解决方案,我很高兴的。
解决方案(再次感谢这个文章的作者,为asp.net作出的贡献)
(中文:http://www.chinaz.com/Webbiz/Seo/040a20P2009.html (一)
http://www.chinaz.com/Program/.NET/042W39322009.html (二)
英文:http://www.manuelabadia.com/blog/PermaLink,guid,7924eaf8-b406-43af-9444-b816f6dfa246.aspx)
DEMO下载地址:http://www.blog-design.cn/upload/2009/4/SEOViewState.zip
注:但此方法在我实际使用中,发现在如果使用ajax控件的话,如UpdatePanel会出现问题,我三个DropDownList选择后,再全表提交后,取不到DropDownList值。希望能解决这个问题的朋友能告诉我一下,解决方法。谢谢.
第六种解决方案:(ViewState保存在服务器端硬盘上.切记不是用Session,否则如果网站访问量过大的话,可能会极度消耗资源。当然保存在服务器端硬盘上是好是坏,现在的说法也是仁者见仁,智者见智)
如果你有一个非常酷的页面,页面上很多东西自动地响应用户操作而展现丰富的变化,你的ViewState是很有可能达到200K的。 using System.IO; protected override object LoadPageStateFromPersistenceMedium() // var viewStateID = (string)((Pair)base.LoadPageStateFromPersistenceMedium()).Second; protected override void SavePageStateToPersistenceMedium(object state) //var fn = Path.Combine(this.Request.PhysicalApplicationPath, @"App_Data/ViewState/" + viewStateID); 不使用Session,因为它会“丢失”。ViewState保存在磁盘上,即使服务器重新启动,也不会丢失页面状态。 void Application_Start(object sender, EventArgs e)
这可以确保绝对稳定可靠地工作。以后请放心使用ViewState,把交互式页面提高水平才是最重要的,不要纠缠在“ViewState太大”上。实际上,由于页面设计不够酷,交互变化看上去不够丰富,ViewState实在是太小太小了。
来源:CSDN http://topic.csdn.net/u/20080530/22/ef0d36a4-6bd4-4eba-9743-b56f080b2161.html
另外,不使用缓存,那么代码就简单一些了,代码变为: |
第七种解决方案:(压缩方法,当然此方法在网上一搜一大把了,无就不在这里详述了)
总上七总方案。因为我们的网站已成型,又不想太大改,我最后还是选择这第一种和第六种相结合的方法。大家如果有兴趣可以看看我的网站:http://www.xbcar.net 西部汽车网 看看哪些地方还会有ViewState的殘留。好。谢谢。如果大家觉得我这个文章还行,转载时请尽量保留出处http://bbs.xbcar.net/showtopic-3168-1.html#3176 ,也算我没白忙一场,谢谢。.如果还有同志们发现了错误或有更好的解决方案及第,请联系我:QQ:64830979,我将不胜感激.