Re: Получить ViewState
От: TK Лес кывт.рф
Дата: 17.08.02 13:56
Оценка: 61 (3)
Здравствуйте 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
От: Igor Soukhov  
Дата: 17.08.02 13:40
Оценка:
Хочу странного — получить данные сериализованне данные из ViewState (уже заенкоденные)
в виде стрима, raw bytes. или строки — все равно. Где копать.
То какую ф-ю (у контрола, формы, или ...) надо переопределить что-бы к этому место весь
ViewState был уже тепленький и я мог, например подменить его перед отправкой на клиетна.
(соответсвенно интересует и обратная операция — получить вьюстейт отправленный с клиента
при постбеке). Интересуют способы реализации на уровне

1)страницы/контролов
2)реализации IHTTPModule/IHttpHandler
* thriving in a production environment *
Re: Получить ViewState
От: IT Россия linq2db.com
Дата: 17.08.02 13:54
Оценка:
Здравствуйте Igor Soukhov, Вы писали:

IS>Хочу странного — получить данные сериализованне данные из ViewState (уже заенкоденные)

IS>в виде стрима, raw bytes. или строки — все равно. Где копать.

Игорь, ты уверен, что ты там всё правильно надизайничал?
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Получить ViewState
От: Igor Soukhov  
Дата: 17.08.02 14:32
Оценка:
Здравствуйте TK, Вы писали:

TK>Здравствуйте Igor Soukhov, Вы писали:

ну сохранение в SQL Server я бы сам написал, но
сам факт чтения мыслей — просто
* thriving in a production environment *
Re[2]: Получить ViewState
От: Igor Soukhov  
Дата: 17.08.02 14:34
Оценка:
Здравствуйте 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 ? На как ?
Re[3]: Получить ViewState
От: TK Лес кывт.рф
Дата: 15.11.02 05:38
Оценка:
Здравствуйте, Аноним, Вы писали:

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.


<configuration>
    <system.web>
        <httpModules>
            <add name="ViewState" type="XXX.Web.ViewStateModule,SQLState" />
        </httpModules>
    </system.web>
</configuration>




Для использования нужно все свои странички наследовать от следующей:


namespace SystemFramework
{
    /// <summary>
    /// Summary description for Page.
    /// </summary>
    public class Page : System.Web.UI.Page
    {
        protected bool ExternalState = true;

        public Page()
        {

        }

        protected override object LoadPageStateFromPersistenceMedium()
        {
            object Result;
            if (ExternalState)
            {
                System.Guid StateCookie = new System.Guid(Request.Params["__VIEWSTATE"]);
                Result = XXX.Web.ViewStateModule.LoadPageViewState(Context, StateCookie);
            }
            else
            {
                Result = base.LoadPageStateFromPersistenceMedium();
            }

            return Result;
        }

        protected override void SavePageStateToPersistenceMedium(object viewState)
        {        
            if (ExternalState)
            {
                System.Guid StateCookie = XXX.Web.ViewStateModule.SavePageViewState(Context, viewState);
                this.RegisterHiddenField("__VIEWSTATE", StateCookie.ToString());
            }
            else
            {
                base.SavePageStateToPersistenceMedium(viewState);
            }
        }

    }
}
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: Получить ViewState
От: Аноним  
Дата: 15.11.02 08:06
Оценка:
Большое спасибо
Re[5]: Получить ViewState
От: kreek  
Дата: 15.11.02 08:15
Оценка:
Здравствуйте <Аноним>, Вы писали:

А>Большое спасибо


Спасибо — слишком много, вот пару баллов — в самый раз.
... << 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) никогда не вызывается.


(я работаю под Win2K Server, MSSQL 2000)
Re[4]: Получить ViewState
От: Canavaro Россия  
Дата: 27.12.06 08:26
Оценка:
Спасибо за пример кода.
Только вот теперь у меня после каждого постбека ругается вот так на ViewState:

[ViewStateException: Invalid viewstate.
Client IP: 127.0.0.1
Port: 6525
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; InfoPath.1; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.03)
ViewState: Ha8M9+AXzhUgv5Ownn9uafXMJjF9aQlwqTTpkgdLSWrEYDe/Ucmzed5ciecYtS6sCjBxU6txjwIMupL73o4g+A==
Referer: http://localhost/web.test/YuraPages/Others.aspx
Path: /web.test/YuraPages/Others.aspx]

[HttpException (0x80004005): The state information is invalid for this page and might be corrupted.]
System.Web.UI.ViewStateException.ThrowError(Exception inner, String persistedState, String errorPageMessage, Boolean macValidationError) +116
System.Web.UI.ClientScriptManager.EnsureEventValidationFieldLoaded() +321
System.Web.UI.ClientScriptManager.ValidateEvent(String uniqueId, String argument) +67
System.Web.UI.Control.ValidateEvent(String uniqueID, String eventArgument) +106
System.Web.UI.WebControls.TextBox.LoadPostData(String postDataKey, NameValueCollection postCollection) +31
System.Web.UI.WebControls.TextBox.System.Web.UI.IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection) +11
System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad) +408
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +6953
System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +154
System.Web.UI.Page.ProcessRequest() +86
System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context) +18
System.Web.UI.Page.ProcessRequest(HttpContext context) +49
ASP.yurapages_others_aspx.ProcessRequest(HttpContext context) in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\web.test\b94dcd3c\fc11344a\App_Web_3enuee-y.4.cs:0
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +154
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64


что тут можно сделать, спасибо !
Re[5]: Получить ViewState
От: Canavaro Россия  
Дата: 27.12.06 13:22
Оценка:
Когда храню ViewState в памяти или в сессии, вобщем не важно где, главное чтобы референс тот же оставался как при сохранении, то всё работает.
А если пытаешься десериализовать, конструируя при этом новый объект, то всё валится как показывал выше.
Помогите, ваще не представляю что это может быть !
Re[6]: Получить ViewState
От: Canavaro Россия  
Дата: 28.12.06 14:32
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>Когда храню ViewState в памяти или в сессии, вобщем не важно где, главное чтобы референс тот же оставался как при сохранении, то всё работает.

C>А если пытаешься десериализовать, конструируя при этом новый объект, то всё валится как показывал выше.
C>Помогите, ваще не представляю что это может быть !

Всё, разобрался !!!
Дето было в том, что там регистрилось HiddenField для хранения ID сессии и имя было "__VIEWSTATE", так она потом перетиралось самим ASP.NET который туда клал пустую строку, потому что я все вызовы на сохранения ViewState перехватывал.
Re[7]: Получить ViewState
От: Canavaro Россия  
Дата: 28.12.06 14:37
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>Здравствуйте, Canavaro, Вы писали:


C>>Когда храню ViewState в памяти или в сессии, вобщем не важно где, главное чтобы референс тот же оставался как при сохранении, то всё работает.

C>>А если пытаешься десериализовать, конструируя при этом новый объект, то всё валится как показывал выше.
C>>Помогите, ваще не представляю что это может быть !

C>Всё, разобрался !!!

C>Дето было в том, что там регистрилось HiddenField для хранения ID сессии и имя было "__VIEWSTATE", так она потом перетиралось самим ASP.NET который туда клал пустую строку, потому что я все вызовы на сохранения ViewState перехватывал.

Может кто знает, как отключить эту фигню вообще, ну чтобы ASP.NET не регистрил это поле, EnableViewState = false — не то !
Re[8]: Получить ViewState
От: mogadanez Чехия  
Дата: 10.01.07 14:14
Оценка:
Здравствуйте, Canavaro, Вы писали:

C>Может кто знает, как отключить эту фигню вообще, ну чтобы ASP.NET не регистрил это поле, EnableViewState = false — не то !


никак... в 1.1 оно рендерится всегда, убрать можно только обрабатывая уже отрендереный результат, обсуждалось .
в 2.0 максимум что можно сделать более менее штатно — отрендерить поле с пустым value.
... << RSDN@Home 1.2.0 alpha rev. 662>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.