.net 网站生成 页面后,会有 <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUIMjU3MTg5ODcPZBYCAgEPZBYeAgEPZBYCZg8QZGQWAWZkAgMPZBY">
这个是Asp.net应用ViewState技术的特征表现,专用来保存页面状态的,为了页面能在PostBack后依然能读取服务器控件原有的状态数据,Asp.net中使用了ViewState技术,而ViewState技术本质上是用一个默认名称为"__VIEWSTATE的Hidden类型表单域来保存和传递数据,然后当在大量使用viewstate时产生的value是相当夸张的(对于SEO来说)。因为我们知道很多搜索引擎的搜索结果中会看到网页大小,在内容和功能确定的前提下,网页字节数越小,打开速度越快,对搜索蜘蛛的爬行越有利。而当我们的ASP.NET页面中的<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="">value值大于200KB或更大时,对搜索是不利的。
www.ynyes.com天度网络 联系sojay.cnblogs.com
虽然我们可以通过三种级别来轻松禁用掉这些数据的往返传递:
Machine级 在machine.config中设置<pages enableViewStateMac='false' />
Application级 在Web Applicatin的web.config中设置<pages enableViewStateMac='false' />
单页面级 在该页面中设置<%@Page enableViewStateMac='false' %>或通过代码设置Page.EnableViewStateMac = false;
可是,如果我们完全能通过禁用ViewState来解决数据传输负担而且不产生副作用的话,那么可能会导致你页面上的一些功能无效。有没有什么好的办法来解决呢。
www.ynyes.com天度网络 联系sojay.cnblogs.com
在网络上找到了一些。转帖过来。
第一种,直接不再页面上输出input type=hidden name="__VIEWSTATE"。这种方法在页面没有使用viewstate的时候可以使用。
Code
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Web;
5
using System.Web.Security;
6
using System.Xml;
7
using System.Text.RegularExpressions;
8
using System.IO;
9![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
10
namespace Blackant.Controls
11![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
12![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
13
/// Summary description for HiddenInputFilter
14
/// </summary>
15
public class HiddenInputHttpModule : IHttpModule
16![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
17![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
IHttpModule Members#region IHttpModule Members
18![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
public void Dispose()
20![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
21
//throw new Exception("The method or operation is not implemented.");
22
}
23![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
24
public void Init(HttpApplication context)
25![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
26
//throw new Exception("The method or operation is not implemented.");
27
context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);
28
}
29![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
#endregion
31![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
32![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
事件#region 事件
33
void context_ReleaseRequestState(object sender, EventArgs e)
34![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
35
HttpResponse response = HttpContext.Current.Response;
36![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
37
if (response.ContentType=="text/html")
38![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
39
HiddenInputFilter filter = new HiddenInputFilter(response.Filter);
40
response.Filter = filter;
41
}
42
}
43
#endregion
44![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
45![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
IRawPath Members#region IRawPath Members
46
private string _rawPath = "";
47
public string GetPath()
48![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
49
return _rawPath;
50
}
51![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
52
#endregion
53
}
54![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
55
public class HiddenInputFilter : Stream
56![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
57![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
私有成员#region 私有成员
58
59
Stream responseStream;
60
long position;
61
StringBuilder responseHtml;
62
#endregion
63![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
64![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
构造#region 构造
65
public HiddenInputFilter(Stream inputStream)
66![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
67
responseStream = inputStream;
68
responseHtml = new StringBuilder();
69
}
70
#endregion
71
72![ContractedSubBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif)
重写的方法#region 重写的方法
73
public override bool CanRead
74![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
75![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return true; }
76
}
77![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
78
public override bool CanSeek
79![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
80![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return true; }
81
}
82![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
83
public override bool CanWrite
84![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
85![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return true; }
86
}
87![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
88
public override void Close()
89![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
90
responseStream.Close();
91
}
92![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
93
public override void Flush()
94![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
95
responseStream.Flush();
96
}
97![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
98
public override long Length
99![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
100![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return 0; }
101
}
102![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
103
public override long Position
104![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
105![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return position; }
106![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ position = value; }
107
}
108![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
109
public override long Seek(long offset, SeekOrigin origin)
110![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
111
return responseStream.Seek(offset, origin);
112
}
113![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
114
public override void SetLength(long length)
115![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
116
responseStream.SetLength(length);
117
}
118![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
119
public override int Read(byte[] buffer, int offset, int count)
120![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
121
return responseStream.Read(buffer, offset, count);
122
}
123![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
124
public override void Write(byte[] buffer, int offset, int count)
125![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
126
string finalHtml = System.Text.UTF8Encoding.Default.GetString(buffer, offset, count);
127
//找到<input type="hidden" name="__VIEWSTATE"
128
string pattern=@"<input type=""hidden"" name=""__VIEWSTATE""[^>]*>";
129
finalHtml=Regex.Replace(finalHtml, pattern, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
130![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
131
// Write the response
132
byte[] data = System.Text.UTF8Encoding.Default.GetBytes(finalHtml);
133
responseStream.Write(data, 0, data.Length);
134
}
135
#endregion
136
137
}
138![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
139![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
140
}
141
编译后生成的dll文件名为Blackant.Controls.dll
然后在web项目中引用这个dll
修改web.config,加入以下内容于System.Web配置节
<
httpModules
>
<
add
name
="HiddenInputFilter"
type
="Blackant.Controls.HiddenInputHttpModule,Blackant.Controls"
/>
</
httpModules
>
其实核心内容很简单
HiddenInputHttpModule中如下指示使用页面过滤器
HiddenInputFilter filter = new HiddenInputFilter(response.Filter);
response.Filter = filter;
HiddenInputFilter 中则
string finalHtml = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
//找到<input type="hidden" name="__VIEWSTATE"
string pattern=@"\<input type=""hidden"" name=""__VIEWSTATE""[^\>]*\>";
finalHtml=Regex.Replace(finalHtml, pattern, string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
替换掉<input type="hidden" name="__VIEWSTATE" ..../>标签
www.ynyes.com天度网络 联系sojay.cnblogs.com
第二种:将ViewState持久化保持在服务器端,此方法不推荐使用。原文地址:
http://topic.csdn.net/u/20080530/22/ef0d36a4-6bd4-4eba-9743-b56f080b2161.html
asp.net2.0里测试的代码,放到页面中,引用using System.IO; using System.Threading;
Code
1![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
解决ViewState过于庞大的问题#region 解决ViewState过于庞大的问题
2
protected override object LoadPageStateFromPersistenceMedium()
3![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
4
string viewStateID = (string)((Pair)base.LoadPageStateFromPersistenceMedium()).Second;
5
string stateStr = (string)Cache[viewStateID];
6
if (stateStr == null)
7![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
8
string fn = Path.Combine(this.Request.PhysicalApplicationPath, @"App_Data/ViewState/" + viewStateID);
9
stateStr = File.ReadAllText(fn);
10
}
11
return new ObjectStateFormatter().Deserialize(stateStr);
12
}
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
protected override void SavePageStateToPersistenceMedium(object state)
15![ExpandedSubBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
string value = new ObjectStateFormatter().Serialize(state);
17
string viewStateID = (DateTime.Now.Ticks + (long)this.GetHashCode()).ToString(); //产生离散的id号码
18
string fn = Path.Combine(this.Request.PhysicalApplicationPath, @"App_Data/ViewState/" + viewStateID);
19
//ThreadPool.QueueUserWorkItem(File.WriteAllText(fn, value));
20
File.WriteAllText(fn, value);
21
Cache.Insert(viewStateID, value);
22
base.SavePageStateToPersistenceMedium(viewStateID);
23
}
24
#endregion
25
www.ynyes.com天度网络 联系sojay.cnblogs.com
第三种:将ViewState的位置调整到页面底部
www.ynyes.com天度网络 联系sojay.cnblogs.com
Code
1
//ViewState的Html标记的正则表达式
2
private static readonly Regex viewStateRegex = new Regex(@"(<input type=""hidden"" name=""__VIEWSTATE"" id=""__VIEWSTATE"" value=""/w(.*)"" />)", RegexOptions.Multiline | RegexOptions.Compiled);
3
//</form>标记的正则表达式
4
private static readonly Regex endFormRegex = new Regex(@"</form>", RegexOptions.Multiline | RegexOptions.Compiled);
5![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
6
protected override void Render(HtmlTextWriter writer)
7![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
8
System.IO.StringWriter stringWriter = new System.IO.StringWriter();
9
HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
10
base.Render(htmlWriter);
11![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
string html = stringWriter.ToString();
13
Match viewStateMatch = viewStateRegex.Match(html);
14
string viewStateString = viewStateMatch.Captures[0].Value;//找出ViewState的Html标记
15
html = html.Remove(viewStateMatch.Index, viewStateMatch.Length);//替换掉ViewState的html标记
16![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
Match endFormMath = endFormRegex.Match(html, viewStateMatch.Index);
18
html = html.Insert(endFormMath.Index, viewStateString);//将ViewState的Html标记插入到</form>标记之前
19
writer.Write(html);
20
21
}
22
www.ynyes.com天度网络 联系sojay.cnblogs.com
不知道还有没有好的方法,解决多SEO友好的优化方式。