Здравствуйте Igor Soukhov, Вы писали:
IS>Хочу странного — получить данные сериализованне данные из ViewState (уже заенкоденные) IS>в виде стрима, raw bytes. или строки — все равно. Где копать. IS>То какую ф-ю (у контрола, формы, или ...) надо переопределить что-бы к этому место весь IS>ViewState был уже тепленький и я мог, например подменить его перед отправкой на клиетна. IS>(соответсвенно интересует и обратная операция — получить вьюстейт отправленный с клиента IS>при постбеке). Интересуют способы реализации на уровне
IS>1)страницы/контролов IS>2)реализации IHTTPModule/IHttpHandler
Для страницы нужно перекрыть SavePageStateToPersistenceMedium/Load...
А вот собственно пример сохранения ViewState в базу SQL сервера (как получить raw bytes наверное можно разобраться ):
public class ViewStateModule : IHttpModule
{
private SqlConnection stateConnection;
private System.Web.HttpApplication application;
public SqlConnection Connection
{
get
{
stateConnection.ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["ViewStateDatabase"];
return stateConnection;
}
}
public ViewStateModule()
{
//
// TODO: Add constructor logic here
//
}
public void Init(System.Web.HttpApplication context)
{
application = context;
System.Collections.Specialized.NameValueCollection appSettings = System.Configuration.ConfigurationSettings.AppSettings;
stateConnection = new SqlConnection(appSettings["ViewStateDatabase"]);
SessionStateModule sessionState = application.Modules["Session"] as SessionStateModule;
sessionState.Start += new System.EventHandler(Session_Start);
sessionState.End += new System.EventHandler(Session_End);
}
public void Dispose()
{
SessionStateModule sessionState = application.Modules["SessionState"] as SessionStateModule;
sessionState.Start -= new System.EventHandler(Session_Start);
sessionState.End -= new System.EventHandler(Session_End);
}
private void Session_End(object sender, EventArgs e)
{
SqlConnection stateConnection = Connection;
using (stateConnection)
{
stateConnection.Open();
SqlCommand sqlDrop = stateConnection.CreateCommand();
sqlDrop.CommandText = "DropSession";
sqlDrop.CommandType = CommandType.StoredProcedure;
sqlDrop.Parameters.Add("@SessionCookie", SqlDbType.VarChar, 50).Value = application.Session.SessionID;
sqlDrop.ExecuteNonQuery();
}
}
private void Session_Start(object sender, EventArgs e)
{
}
public static System.Guid SavePageViewState(HttpContext context, object state)
{
ViewStateModule _this = ViewStateModule.Current;
System.Guid Result = System.Guid.Empty;
if (_this != null)
{
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
{
System.Web.UI.LosFormatter losf = new System.Web.UI.LosFormatter();
losf.Serialize(stream, state);
SqlConnection stateConnection = _this.Connection;
using (stateConnection)
{
stateConnection.Open();
SqlCommand sqlSave = _this.stateConnection.CreateCommand();
sqlSave.CommandText = "SavePageViewState";
sqlSave.CommandType = CommandType.StoredProcedure;
sqlSave.Parameters.Add("@SessionCookie", SqlDbType.VarChar, 50).Value = _this.application.Session.SessionID;
sqlSave.Parameters.Add("@ViewState", SqlDbType.Image).Value = stream.ToArray();
Result = new System.Guid(sqlSave.ExecuteScalar().ToString());
}
}
}
return Result;
}
public static object LoadPageViewState(HttpContext context, System.Guid stateId)
{
ViewStateModule _this = ViewStateModule.Current;
object Result = null;
if (_this != null)
{
SqlConnection stateConnection = _this.Connection;
using (stateConnection)
{
stateConnection.Open();
SqlCommand sqlLoad = stateConnection.CreateCommand();
sqlLoad.CommandText = "LoadPageViewState";
sqlLoad.CommandType = CommandType.StoredProcedure;
sqlLoad.Parameters.Add("@RequestStamp", SqlDbType.UniqueIdentifier).Value = stateId;
using (System.Data.SqlClient.SqlDataReader reader = sqlLoad.ExecuteReader())
{
if (reader.Read())
{
System.IO.MemoryStream stream = new System.IO.MemoryStream(reader[0] as byte []);
System.Web.UI.LosFormatter losf = new System.Web.UI.LosFormatter();
Result = losf.Deserialize(stream);
}
}
}
}
return Result;
}
public static ViewStateModule Current
{
get
{
return HttpContext.Current.ApplicationInstance.Modules["ViewState"] as ViewStateModule;
}
}
}
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Хочу странного — получить данные сериализованне данные из ViewState (уже заенкоденные)
в виде стрима, raw bytes. или строки — все равно. Где копать.
То какую ф-ю (у контрола, формы, или ...) надо переопределить что-бы к этому место весь
ViewState был уже тепленький и я мог, например подменить его перед отправкой на клиетна.
(соответсвенно интересует и обратная операция — получить вьюстейт отправленный с клиента
при постбеке). Интересуют способы реализации на уровне
Здравствуйте Igor Soukhov, Вы писали:
IS>Хочу странного — получить данные сериализованне данные из ViewState (уже заенкоденные) IS>в виде стрима, raw bytes. или строки — все равно. Где копать.
Игорь, ты уверен, что ты там всё правильно надизайничал?
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте IT, Вы писали:
IS>>Хочу странного — получить данные сериализованне данные из ViewState (уже заенкоденные) IS>>в виде стрима, raw bytes. или строки — все равно. Где копать.
IT>Игорь, ты уверен, что ты там всё правильно надизайничал?
не — щас сделаю енту заплатку — и будет верняк. конечно
это workaround, но если идею довести до ума — то можно выдавать
и за solutition
* thriving in a production environment *
Re[2]: Получить ViewState
От:
Аноним
Дата:
14.11.02 13:52
Оценка:
TK>Для страницы нужно перекрыть SavePageStateToPersistenceMedium/Load...
TK>А вот собственно пример сохранения ViewState в базу SQL сервера (как получить raw bytes наверное можно разобраться
Я попытался у себя использовать этот код.
Создал таблицу и SPs
CREATE TABLE [dbo].[tblOdusViewState] (
[RequestStamp] [uniqueidentifier] NOT NULL ,
[SessionCookie] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[ViewState] [image] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE PROCEDURE LoadPageViewState
(
@RequestStamp UniqueIdentifier
)
AS
CREATE PROCEDURE SavePageViewState
(
@SessionCookie varchar(50),
@ViewState image,
@RequestStamp UniqueIdentifier OUTPUT
)
AS
SELECT @RequestStamp = RequestStamp from tblOdusViewState where SessionCookie = @SessionCookie
if @@ROWCOUNT > 0
begin
update tblOdusViewState set ViewState=@ViewState where SessionCookie = @SessionCookie
end
else
begin
insert into tblOdusViewState (SessionCookie, ViewState) values (@SessionCookie, @ViewState)
SELECT @RequestStamp = RequestStamp from tblOdusViewState where SessionCookie = @SessionCookie
end
CREATE PROCEDURE DropSession
(
@SessionCookie VarChar(50)
)
AS
delete from tblOdusViewState where SessionCookie = @SessionCookie
Правильно ли все ?
И каким образом можно теперь этот класс ViewStateModule использовать ?
Я так понял где в Global.asax ? На как ?
Здравствуйте, Аноним, Вы писали:
TK>>Для страницы нужно перекрыть SavePageStateToPersistenceMedium/Load...
TK>>А вот собственно пример сохранения ViewState в базу SQL сервера (как получить raw bytes наверное можно разобраться
А>Я попытался у себя использовать этот код. А>Создал таблицу и SPs
А>Правильно ли все ?
Не знаю. Вот оригинальный код.
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Session_ViewState_FK1]') and OBJECTPROPERTY(id, N'IsForeignKey') = 1)
ALTER TABLE [dbo].[ViewState] DROP CONSTRAINT Session_ViewState_FK1
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[DropLostSession]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[DropLostSession]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[DropSession]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[DropSession]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[LoadPageViewState]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[LoadPageViewState]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[SavePageViewState]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[SavePageViewState]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Session]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Session]
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[ViewState]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[ViewState]
GO
CREATE TABLE [dbo].[Session] (
[SessionID] [int] IDENTITY (1, 1) NOT NULL ,
[SessionCookie] [varchar] (50) COLLATE Cyrillic_General_CI_AS NOT NULL ,
[Created] [datetime] NOT NULL ,
[LastAccess] [datetime] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[ViewState] (
[StateID] [int] IDENTITY (1, 1) NOT NULL ,
[SessionID] [int] NOT NULL ,
[RequestStamp] [uniqueidentifier] NULL ,
[PageState] [image] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE PROCEDURE dbo.DropLostSession
AS
BEGIN
SET NOCOUNT ON
DELETE FROM Session WHERE LastAccess < DATEADD(dd, -2, GETDATE())
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE Procedure DropSession
@SessionCookie AS VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON
DELETE FROM Session WHERE SessionCookie=@SessionCookie
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE Procedure LoadPageViewState
@RequestStamp AS UniqueIdentifier
AS
BEGIN
SET NOCOUNT ON
DECLARE @SessionID INT
DECLARE @StateID INT
SELECT @SessionID=SessionID, @StateID=StateID FROM ViewState WHERE RequestStamp=@RequestStamp
IF @SessionID IS NOT NULL
BEGIN
UPDATE Session SET LastAccess=GETDATE() WHERE SessionID=@SessionID
SELECT PageState FROM ViewState WHERE StateID=@StateID
END
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE Procedure SavePageViewState
@SessionCookie AS VARCHAR(50),
@ViewState AS IMAGE
AS
BEGIN
SET NOCOUNT ON
DECLARE @SessionID INT
SELECT @SessionID=SessionID FROM Session WHERE SessionCookie=@SessionCookie
IF @SessionID IS NULL
BEGIN
INSERT INTO Session (SessionCookie) VALUES (@SessionCookie)
SELECT @SessionID=@@IDENTITY
END
ELSE
BEGIN
UPDATE Session SET LastAccess=GETDATE() WHERE SessionID=@SessionID
END
INSERT INTO ViewState (SessionID, PageState) VALUES (@SessionID, @ViewState)
SELECT RequestStamp FROM ViewState WHERE StateID=@@IDENTITY
END
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
А>И каким образом можно теперь этот класс ViewStateModule использовать ? А>Я так понял где в Global.asax ? На как ?
Нет в Global.asax не надо. Нужно подключить его в виде модуля в web.config.
Здравствуйте <Аноним>, Вы писали:
А>Большое спасибо
Спасибо — слишком много, вот пару баллов — в самый раз.
... << RSDN@Home 1.0 alpha 12 >>
Re[6]: Получить ViewState
От:
Аноним
Дата:
15.11.02 12:59
Оценка:
хм...хорошо, мне и пары баллов не жалко... А что тут по баллам комиссионные выплачивают ? (похоже в оффтоп скатываемся)
K>Спасибо — слишком много, вот пару баллов — в самый раз.
Еще пара вопросов к вышеприведенным исходникам:
1. Может так быть что SQL script содержит не все необходимое для нормальной работы ?
Может быть нужны еще тригеры или еще что то ? По крайней мере у меня не "завелось" все с первого раза, пришлось поправить таблицы и sp.
2. База данных не чистится. Может быть это как то косвенно связано с п. 1 или нужно еще какие то моменты
учитывать?
private void Session_End(object sender, EventArgs e) никогда не вызывается.
Когда храню ViewState в памяти или в сессии, вобщем не важно где, главное чтобы референс тот же оставался как при сохранении, то всё работает.
А если пытаешься десериализовать, конструируя при этом новый объект, то всё валится как показывал выше.
Помогите, ваще не представляю что это может быть !
Здравствуйте, Canavaro, Вы писали:
C>Когда храню ViewState в памяти или в сессии, вобщем не важно где, главное чтобы референс тот же оставался как при сохранении, то всё работает. C>А если пытаешься десериализовать, конструируя при этом новый объект, то всё валится как показывал выше. C>Помогите, ваще не представляю что это может быть !
Всё, разобрался !!!
Дето было в том, что там регистрилось HiddenField для хранения ID сессии и имя было "__VIEWSTATE", так она потом перетиралось самим ASP.NET который туда клал пустую строку, потому что я все вызовы на сохранения ViewState перехватывал.
Здравствуйте, Canavaro, Вы писали:
C>Здравствуйте, Canavaro, Вы писали:
C>>Когда храню ViewState в памяти или в сессии, вобщем не важно где, главное чтобы референс тот же оставался как при сохранении, то всё работает. C>>А если пытаешься десериализовать, конструируя при этом новый объект, то всё валится как показывал выше. C>>Помогите, ваще не представляю что это может быть !
C>Всё, разобрался !!! C>Дето было в том, что там регистрилось HiddenField для хранения ID сессии и имя было "__VIEWSTATE", так она потом перетиралось самим ASP.NET который туда клал пустую строку, потому что я все вызовы на сохранения ViewState перехватывал.
Может кто знает, как отключить эту фигню вообще, ну чтобы ASP.NET не регистрил это поле, EnableViewState = false — не то !
Здравствуйте, Canavaro, Вы писали:
C>Может кто знает, как отключить эту фигню вообще, ну чтобы ASP.NET не регистрил это поле, EnableViewState = false — не то !
никак... в 1.1 оно рендерится всегда, убрать можно только обрабатывая уже отрендереный результат, обсуждалось .
в 2.0 максимум что можно сделать более менее штатно — отрендерить поле с пустым value.