优化大型网站的视图状态管理

在大型网站中,页面数量众多,用户量大,因此减少客户端和服务器之间来回传输的视图状态是提高性能的关键。本文将介绍一种将视图状态存储在数据库中的策略,以及如何通过.NET代码来实现这一策略。

视图状态表的创建

首先,需要创建一个用于存储视图状态的数据库表。这个表将包含一个唯一标识视图状态的键(View_State_Key),一个存储视图状态字符串的列(View_State_Value),以及一个记录插入时间的列(Insert_Time)。

CREATE TABLE [dbo].[View_State] ( View_State_Key NVARCHAR(250) NOT NULL, View_State_Value NVARCHAR(MAX) NULL, Insert_Time DATETIME NOT NULL CONSTRAINT DF_View_State_Insert_Time DEFAULT (GETDATE()), CONSTRAINT PK_View_State PRIMARY KEY CLUSTERED ( View_State_Key ASC ) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

这个表的设计允许将视图状态的键注入到网页中,而不是实际的视图状态。这样可以减少数据传输量。

存储过程的创建

接下来,需要创建一些存储过程来获取和设置视图状态。这些存储过程非常简单,但非常有效。

CREATE PROCEDURE [dbo].[sp_get_view_state] @View_State_Key NVARCHAR(250) AS BEGIN SET NOCOUNT ON; SELECT TOP 1 View_State_Value FROM View_State WITH (NOLOCK) WHERE View_State_Key = @View_State_Key END CREATE PROCEDURE [dbo].[sp_set_view_state] @View_State_Key NVARCHAR(250), @View_State_Value NVARCHAR(MAX) AS BEGIN SET XACT_ABORT ON; BEGIN TRY BEGIN TRANSACTION INSERT INTO View_State(View_State_Key, View_State_Value) VALUES (@View_State_Key, @View_State_Value) COMMIT TRANSACTION RETURN 0 END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION RETURN -1 END CATCH END

这些存储过程将用于从数据库中检索和存储视图状态。

删除视图状态的存储过程

还需要一个存储过程来删除过期的视图状态。这个存储过程将删除所有至少2小时没有被访问的视图状态。

CREATE PROCEDURE [dbo].[sp_delete_view_state] AS BEGIN SET NOCOUNT ON; DECLARE @hours INT = 2 DELETE FROM View_State WHERE DATEDIFF(hour, Insert_Time, GETDATE()) > @hours END

这个存储过程将由SQL Server作业定期执行,而不是直接从.NET代码中执行。

视图状态管理

ViewStateManagement类负责读取和写入视图状态。它在网页和数据库之间进行协调。SetViewState方法存储视图状态。首先,该方法使用专用的.NET类LosFormatter将视图状态对象序列化为字符串。然后,它构建一个唯一标识视图状态的键。

public static class ViewStateManagement { public static bool SetViewState( Page page, HttpContext context, string connectionString, object viewState, string uniqueKey = null) { StringBuilder sb = new StringBuilder(); using (StringWriter swr = new StringWriter(sb)) new System.Web.UI.LosFormatter().Serialize(swr, viewState); string viewStateKey = string.Format("VIEWSTATE_{0}_{1}_{2}", uniqueKey, GetIP(context), DateTime.Now.Ticks); bool succeeded = SetViewState(connectionString, viewStateKey, sb.ToString()); if (succeeded) page.ClientScript.RegisterHiddenField("__VIEWSTATE_KEY", viewStateKey); return succeeded; } }

Get方法从HTTP请求中提取__VIEWSTATE_KEY。有了这个键,它将查询数据库,从数据库中获取视图状态字符串,并使用LosFormatter将其反序列化为对象。

public static class ViewStateManagement { public static object GetViewState(HttpContext context, string connectionString) { if (context == null || context.Request == null) return null; string viewStateKey = context.Request.Form["__VIEWSTATE_KEY"]; if (!string.IsNullOrEmpty(viewStateKey) && viewStateKey.StartsWith("VIEWSTATE_")) { string viewState = GetViewState(connectionString, viewStateKey); if (!string.IsNullOrEmpty(viewState)) return new System.Web.UI.LosFormatter().Deserialize(viewState); } return null; } } public abstract class BasePage : System.Web.UI.Page { protected override void SavePageStateToPersistenceMedium(object viewState) { string uniqueKey = null; string connectionString = HttpContext.Current.Session["ConnectionString"] as string; bool succeeded = ViewStateManagement.SetViewState(this, HttpContext.Current, connectionString, viewState, uniqueKey); if (!succeeded) base.SavePageStateToPersistenceMedium(viewState); } protected override object LoadPageStateFromPersistenceMedium() { string connectionString = HttpContext.Current.Session["ConnectionString"] as string; object viewState = ViewStateManagement.GetViewState(HttpContext.Current, connectionString); if (viewState != null) return viewState; else return base.LoadPageStateFromPersistenceMedium(); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485