PDA

View Full Version : انتقال ViewState به انتهای صفحه



actros
یک شنبه 24 بهمن 1389, 05:18 صبح
تمام کاری که باید انجام بدید قرار دادن dll در bin پروژه و افزودن این خط به Web.config ئه : (برای دانلود dll اینجا (http://www.mediafire.com/?xd8j4blnepcubxr)کلیک کنید)






web.config
<system.web>
<httpModules>
<!-- To use the C# version, use this add instead of the other one
<add type="StructuredSolutions.MoveViewState.MoveViewStateMod ule, StructuredSolutions.MoveViewStateCS"
name="MoveViewStateModule" />
-->
<add type="StructuredSolutions.MoveViewState.MoveViewStateMod ule, StructuredSolutions.MoveViewStateVB"
name="MoveViewStateModule" />
</httpModules>
</system.web>




حالا اونائی که میخان در مورد نحوه عملکرد این ماژول بیشتر بدونن ادامه پست رو مطالعه کنن :


هدف از این کار SEO Friendly تر کردن سایته.چرا که میگن Indexer هائی نظیر گوگل فقط بخش های ابتدائی صفحه رو میخونن و Index میکنن.

پس بهتره مطالب مفید تری از ViewState اون بالاها داشته باشیم :دی

این ایده اولین بار از طرف Scott Hanselman و Jeff Atwood مطرح شده ولی من با کامپوننت ساخت اونا مشکل داشتم و همیشه جواب نمیداد.

ولی یه جا دیگه ورژن اصلاح شدشو پیدا کردم.که ترجمشو براتون میذارم:برای اینکار عده ای متد Render رو تو کلاس BasePage بازنویسی(override) می کنن ولی راه حل بهتر استفاده از HttpModule ئه (کاری که تو
DoteNetNuke انجام میشه) مزیت اصلی استفاده از HttpModule عدم نیاز به تعریف کلاس BasePage و عدم نیاز به کامپایل کردنه. یه dll تمام چیزیه که بهش نیاز داریم. در زیر به چند نکته مهم اشاره می کنم :


- این ماژول باید قبل از ماژولهای Compression و ماژولهای تغییر دهنده html قرار بگیره.


- این ماژول فرض میکنه شروع ViewState بعد از اولین تگ </form> ئه .لذا در مواقعی که چندین تگ <from> تو صفحه داشته باشید ممکنه به درستی کار نکنه.


- همچنین این ماژول فرض رو بر این میذاره که encoding و decoding محتویات صفحه شما با استاندارد UTF8 صورت می گیره.اگه از استاندارد دیگه ای استفاده می کنید صفحه شما به درستی کار میکنه ولی انتقال ViewState به انتهای صفحه صورت نمی گیره.
خود کد چیز پیچیده ای نداره. یه کلاس MoveViewStateModule و یک کلاس MoveViewStateFilter داریم. کلاس MoveViewStateModule ایترفیس IHttpModule رو ایپلیمنت می کنه. درون رویداد IHttpModule.Init یه event handler به رویداد HttpApplication.BeginRequest اضافه می شه. درون رویداد BeginRequest یه MoveViewStateFilter ساخته شده و به Response اعمال میشه.

MoveViewStateModule.vb



Public Class MoveViewStateModule
Implements System.Web.IHttpModule

Public Sub Dispose() Implements System.Web.IHttpModule.Dispose
End Sub

Public Sub Init(ByVal context As System.Web.HttpApplication)
Implements System.Web.IHttpModule.Init
AddHandler context.BeginRequest, AddressOf BeginRequestHandler
End Sub

Private Sub BeginRequestHandler(ByVal sender As Object, ByVal e As EventArgs)
Dim application As System.Web.HttpApplication = CType(sender, System.Web.HttpApplication)
application.Response.Filter = New MoveViewStateFilter(application.Response.Filter)
End Sub
End Class



MoveViewStateModule.cs


public class MoveViewStateModule : System.Web.IHttpModule
{
public MoveViewStateModule() {}
void System.Web.IHttpModule.Dispose() {}

void System.Web.IHttpModule.Init(System.Web.HttpApplica tion context)
{
context.BeginRequest += new EventHandler(this.BeginRequestHandler);
}

void BeginRequestHandler(object sender, EventArgs e)
{
System.Web.HttpApplication application = (System.Web.HttpApplication) sender;
application.Response.Filter = new MoveViewStateFilter(application.Response.Filter);
}
}Response.Filter در واقع یه System.IO.Stream ئه . هر فیلتری که ما اعمال می کنیم باید مثل زنجیر به فیلتر قبلی متصل بشه. فیلتر Upstreame عمل Write روی MoveViewStateFilter
رو انجام میده و MoveViewStateFilter عمل Write درون فیلتر downstream رو به عهده می گیره.MoveViewStateFilter به عنوان گونه ای از System.IO.MemoryStream ایمپلیمنت شده و هرچیزی که در اون نوشته میشه رو در بافر write می کنه.هنگامی فراخوانی متد Close بافر به رشته

(string) تبدیل شده و عبارت __VIEWSTATE در اون مورد جستجو قرار می گیره.اگر جستجو نتیجه ای در بر داشته باشه ViewState به انتهای فرم انتقال داده میشه.


MoveViewStateFilter.vb


Public Class MoveViewStateFilter
Inherits System.IO.MemoryStream

Private _filter As System.IO.Stream
Private _filtered As Boolean = False

''' <param name="filter">A reference to the downstream HttpResponse.Filter.</param>
Public Sub New(ByVal filter As System.IO.Stream)
_filter = filter
End Sub

''' <remarks>
''' The contents of this filter are written to the downstream filter after the hidden
''' __VIEWSTATE form field is moved.
''' </remarks>
''' <summary>Closes this filter stream.</summary>
Public Overrides Sub Close()
If _filtered Then
If Me.Length > 0 Then
Dim bytes() As Byte
Dim content As String = System.Text.Encoding.UTF8.GetString(Me.ToArray)
Dim viewstateStart As Integer
viewstateStart = content.IndexOf("<input type=""hidden"" name=""__VIEWSTATE""")
If viewstateStart >= 0 Then
Dim viewstateEnd As Integer
viewstateEnd = content.IndexOf("/>", viewstateStart) + 2
Dim viewstate As String
viewstate = content.Substring(viewstateStart, viewstateEnd - viewstateStart)
content = content.Remove(viewstateStart, viewstateEnd - viewstateStart)
Dim formEndStart As Integer = content.IndexOf("</form>")
If formEndStart >= 0 Then
content = content.Insert(formEndStart, viewstate)
End If
bytes = System.Text.Encoding.UTF8.GetBytes(content)
Else
bytes = Me.ToArray
End If
_filter.Write(bytes, 0, bytes.Length)
End If
_filter.Close()
End If
MyBase.Close()
End Sub

Public Overrides Sub Write(ByVal buffer() As Byte, _
ByVal offset As Integer, ByVal count As Integer)
If Not System.Web.HttpContext.Current Is Nothing _
AndAlso System.Web.HttpContext.Current.Response.ContentTyp e = "text/html" Then
MyBase.Write(buffer, offset, count)
_filtered = True
Else
_filter.Write(buffer, offset, count)
_filtered = False
End If
End Sub

End Class

MoveViewStateFilter.cs


using System;

namespace StructuredSolutions.MoveViewState
{
/// <summary>Moves the hidden __VIEWSTATE form field to the end of the form.</summary>
public class MoveViewStateFilter : System.IO.MemoryStream
{
System.IO.Stream _filter;
bool _filtered = false;

/// <param name="filter">A reference to the downstream HttpResponse.Filter.</param>
public MoveViewStateFilter(System.IO.Stream filter)
{
_filter = filter;
}

/// <summary>Closes this filter stream.</summary>
/// <remarks>
/// The contents of this filter are written to the downstream filter after the hidden
/// __VIEWSTATE form field is moved.
/// </remarks>
public override void Close()
{
if (_filtered)
{
if (this.Length > 0)
{
byte[] bytes;
string content = System.Text.Encoding.UTF8.GetString(this.ToArray() );
int viewstateStart = content.IndexOf("<input type=\"hidden\" name=\"__VIEWSTATE\"");
if (viewstateStart >= 0)
{
int viewstateEnd = content.IndexOf("/>", viewstateStart) + 2;
string viewstate = content.Substring(viewstateStart, viewstateEnd - viewstateStart);
content = content.Remove(viewstateStart, viewstateEnd - viewstateStart);
int formEndStart = content.IndexOf("</form>");
if (formEndStart >= 0)
content = content.Insert(formEndStart, viewstate);
bytes = System.Text.Encoding.UTF8.GetBytes(content);
}
else
{
bytes = this.ToArray();
}
_filter.Write(bytes, 0, bytes.Length);
}
_filter.Close();
}
base.Close();
}

public override void Write(byte[] buffer, int offset, int count)
{
if ((System.Web.HttpContext.Current != null)
&& ("text/html" == System.Web.HttpContext.Current.Response.ContentTyp e))
{
base.Write(buffer, offset, count);
_filtered = true;
}
else
{
_filter.Write(buffer, offset, count);
_filtered = false;
}
}
}منبع:
hadimvc.mihanblog.com