Archive for October, 2007

How to replace our Sessions State strategy in Web Client Software Factory with a custom one

With Web Client Software Factory, when you require your application to store information in the session state, you can use the Composite Web Application Block class StateValue to store the information. This class supports code that runs both in a Web server environment (the session is available, and data is stored there) and outside of a Web server environment (no session is available, such as when you run your unit tests, and the data is stored in memory). Therefore, StateValue objects are useful to increase the testing surface of your application.

By default, StateValue objects use the ASP.NET Session when the code is running in a Web server. However, when persisting session information in ASP.NET web applications, developers may not want to rely on the ASP.NET Session state and might prefer to use their own persistence mechanism that, for example, uses a custom database.

The purpose of this post is to demonstrate how to create a new Session State Locator Service, and wire everything up so the StateValue injection occurs with your custom state persistence mechanism.

Implementation

1) Create a class that implements the IHttpSessionState interface. In this example, the session information is stored in a database.

public class MySessionState : IHttpSessionState
{
    private DatabaseHelper _dbHelper;
    private string _userName;

    public MySessionState()
    {
        _dbHelper = new DatabaseHelper(/* connection string */);
        _userName = HttpContext.Current.User.Identity.Name;
    }

    #region IHttpSessionState Members
    public object this[string name]
    {
        get { return dbHelper.GetValue(_userName, name); }
        set { dbHelper.SetValue(_userName, name, value); }
    }

    /// …
    /// Our IHttpSessionState implementation
    /// …
    #endregion
}

 

2) Create a class that implements the Microsoft.Practices.CompositeWeb.Interfaces.ISessionStateLocatorService interface. This service must return an instance of the class that you implemented in the previous step. The Composite Web Application Block uses this service to inject an instance of IHttpSessionState to StateValue objects.

public class MySessionStateLocatorService : ISessionStateLocatorService
{
    #region ISessionStateLocatorService Members

    public System.Web.SessionState.IHttpSessionState GetSessionState()
    {
        return new MySessionState();
    }

    #endregion
}

 

3) Create a class that inherits from WebClientApplication class. In this class you will register your custom ISessionStateLocatorService.

public class MyWebApplication : WebClientApplication
{
}

 

4) Override the AddRequiredServices method, and add code that removes the SessionStateLocatorService service and registers the custom one.

public class MyWebApplication : WebClientApplication
{
    protected override void AddRequiredServices()
    {
        base.AddRequiredServices();

        base.RootContainer.Services.Remove();
        this.RootContainer.Services.AddNew();
    }
}

  

Using the Custom Implementation

To use the custom implementation you have to update the Global.asax file to specify the custom global application class.

<%@ Application Language=“C#” Inherits=“MyCustomSessionState.MyWebApplication” %>

After that, you can use StateValue objects to manage state across requests in the same way as always:

1) Add a public field of type StateValue to your class, where T is the type of the object you want to persist across requests (in this case, the Customer class)

public StateValue _currentCustomer;

 

2) To access the info, use the Value property of the StateValue class.

// Set the value
_currentCustomer.Value = new Customer();

// Get the value
Customer customer = _currentCustomer.Value;

 

You can find more information about the StateValue class in the topic Developing Web Client Applications | How to: Use Session State with Unit Testing from the WCSF Documentation.

Important: The code available for download is provided “as is” with no warranties of any kind.

Attachment(s): MyCustomSessionState.zip

How to: Run the Contextual AutoComplete Bundle with a newer version of the Ajax Control Toolkit

Symptom

When you use a newer version of the AjaxControlToolkit in the AutoComplete QuickStart, a runtime error occurs:

“Parser Error Message: Could not load file or assembly ‘AjaxControlToolkit, Version=1.0.10618.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e’ or one of its dependencies.”

parserError

Root Cause

Since the AjaxControlToolkit.dll assembly is strong named, you must use the same assembly version that the AjaxControlToolkit.WCSFExtensions was compiled against (because the CLR attempts to bind –by default- with the exact version of an assembly that the application was built with).

Workaround

(Note: I smoke tested the AutoComplete QuickStart with AjaxControlToolkit 1.0.10920.x and I faced some issues; therefore, I suggest you not to run the QuickStart with this version. Read the known issues section for more details.)

You can use assembly version redirection to avoid having to rebuild the AjaxControlToolkit.WCSFExtensions.dll assembly. With the redirection mechanism, you can tell the CLR to redirect one assembly version to another:

1) Copy AjaxControlToolkit.dll (and all the sub-directories) located in the SampleWebSite\Bin folder of the toolkit’s zip file to the Lib\AjaxControlToolkit folder of the QuickStart directory.

2) Open the AutoComplete QuickStart.

3) Add the following XML code to the AutoCompleteQuickStart Web.config file after the close tag. Replace the newVersion attribute to match the version of the AJAX Control Toolkit that you are using (for example, the current version is 1.0.10920.32880).

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

        <assemblyIdentity name="AjaxControlToolkit"
                          publicKeyToken="28f01b0e84b6d53e"
                          culture="neutral"/>
        <bindingRedirect oldVersion="1.0.10618.0"
                         newVersion="1.0.10920.32880"/>

Note: You can find the assembly version number in the properties of the reference to the AjaxControlToolkit assembly

AjaxControlToolkitVersion

4) Run the QuickStart.

 

AjaxControlToolkit (1.0.10920.x) issues

This section describes the issues faced when running the Autocomplete QuickStart with the AjaxControlToolkit 1.0.10920.x.

o No autocomplete list is shown until you hit the backspace key.

toolkit_issue1

o On Numeric fields, you get a list of “undefined” words. This seems to be related with an issue with this version of the the AjaxControlToolkit.

Note: This issue was resolved with changeset 27752. More information, go to here.

toolkit_issue2