locked
SqlServerPersistState State Management in User Interface Application Block RRS feed

  • General discussion

  • I have found the below problem while applying SqlServerPersistState state management in UI Application block.


    UIProcess Application Block because it was giving Invalid Cast exception in the DataHelper.cs file line 44 of Microsoft Data application block. The function is as follows:

    Private Shared Sub AttachParameters(ByVal command As IDbCommand, ByVal commandParameters() As IDbDataParameter)
     
    If (command Is Nothing) Then Throw New ArgumentNullException("command")
    If (Not commandParameters Is Nothing) Then

    Dim p As OleDbParameter

    For Each p In commandParameters < -- error in this line
    If (Not p Is Nothing) Then
    ' Check for derived output value with no value assigned

    If (p.Direction = ParameterDirection.InputOutput OrElse p.Direction = ParameterDirection.Input) AndAlso p.Value Is Nothing Then

    p.Value = DBNull.Value

    End If

    command.Parameters.Add(p)
    End If

    Next p

    End If

    End Sub

    Data application block is called from the UIProcess application block while the SQL Server managed state is configured in the UIProcess application block.

    The file name is SqlServerPersistState.cs in the UIProcess App block. Within this file some stored procedures are called to save, retrieve, remove the state from the database. The parameters of the stored procedures are passed as

     

    SqlParameter rather than OleDbParameter. One of the example is as below:

    [SqlClientPermission(System.Security.Permissions.SecurityAction.Demand)]
    public void Save(State state)

    {

    BinaryFormatter formatter =new BinaryFormatter();
    MemoryStream memoryStream =new MemoryStream();

    formatter.Serialize(memoryStream, state);
    byte[] serializedObject = memoryStream.GetBuffer();

    try

    {

    SqlParameter binState = new SqlParameter(DbParamXmlState, System.Data.SqlDbType.Image );
    binState.Value = serializedObject;

    DataHelper.ExecuteNonQuery( _connectionString,
    CommandType.StoredProcedure,
    DbInsertState,
    new SqlParameter[] { <-- Passed as SQLParameter
    new SqlParameter(DbParamStateGuid, state.TaskId),
    binState} );

    );

    }

    catch (Exception ex)

    {

    throw new ApplicationException( Resource.ResourceManager[Resource.Exceptions.RES_ExceptionSQLStatePersistenceProviderDehydrate], ex );

    }

    finally

    {

    memoryStream.Close();

    }

    }

     

    I changed the above code block to the below code block:

    [SqlClientPermission(System.Security.Permissions.SecurityAction.Demand)]
    public void Save(State state)

    {

    BinaryFormatter formatter =new BinaryFormatter();
    MemoryStream memoryStream =new MemoryStream();

    formatter.Serialize(memoryStream, state);

    byte[] serializedObject = memoryStream.GetBuffer();

    try
    {


    //Original Code

    // SqlParameter binState = new SqlParameter(DbParamXmlState, System.Data.SqlDbType.Image );

    // binState.Value = serializedObject;

    //

    // DataHelper.ExecuteNonQuery( _connectionString,

    // CommandType.StoredProcedure,

    // DbInsertState,

    // new SqlParameter[] {

    // new SqlParameter(DbParamStateGuid, state.TaskId),

    // binState} );

     
    //Changed Code

    OleDbParameter binState =new OleDbParameter(DbParamXmlState, System.Data.OleDb.OleDbType.Binary );

    binState.Value=serializedObject;

    DataHelper.ExecuteNonQuery(_connectionString,
    CommandType.StoredProcedure,
    DbInsertState,
    new OleDbParameter[]{
    new OleDbParameter(DbParamStateGuid, state.TaskId),
    binState});

    }

    catch (Exception ex)

    {
    throw new ApplicationException( Resource.ResourceManager[Resource.Exceptions.RES_ExceptionSQLStatePersistenceProviderDehydrate], ex );
    }

    finally
    {
    memoryStream.Close();
    }

    }

    I changed the below two configuration items in my application web.config:

    <statePersistenceProvider
       name="SqlServerPersistState"
       type="Framework.ApplicationBlocks.UIProcess.SqlServerPersistState, Framework.ApplicationBlocks.UIProcess, Version=2.0.0.0,Culture=neutral,PublicKeyToken=5003557dda2b0d76"
       connectionString="Provider=SQLOLEDB;server=XXXX,1433;initial catalog=UIPState;User ID=XXXX;Password=XXXX"/>

    Also tried the integrated security in connection string.

    and


    <navigationGraph iViewManager="UserControlViewManager" name="MainGraph" state="XXXXXX"
    statePersist="SqlServerPersistState" startView="Home" cacheExpirationMode="Absolute" cacheExpirationInterval="12:00:00">

    My application is running on .NET 1.1.4322 and its a web application.

    This is now working fine. But my question is whether it is really a bug or there is some other way to handle this without the application block code change?

    Thanks in Advance,
    Niloy

     

    • Edited by niloy2000 Wednesday, May 6, 2009 2:04 PM The formatting didn't work
    Wednesday, May 6, 2009 1:56 PM