Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Achieve multiple tasks (child window) functionality in a web application using UIAPB

0.00/5 (No votes)
22 Aug 2006 1  
Describes a solution to achieve shared session, multiple tasks functionality using the User Interface Process Application Block 2.0.

Introduction

I have seen many people crying on forums for functionality for running multiple tasks by a single user while using the User Interface Process Application Block (UIPAB). Especially if it was a web application (in fact, every question did mention a web application). The official documentation of UIPAB suggests implementing the ITask interface and explicitly handling situations where multiple tasks are to be simultaneously run by a single user (no code example has been provided though). This article deals with this very problem by making some small changes to the code of UIPAB. Note that UIPAB is available for download at Microsoft’s Patterns & Practices website.

The hidden problem

There is one basic problem in achieving a multiple windows (with multiple tasks) scenario with UIPAB.

UIPAB stores the ActiveTaskID in the session variable which is shared by all browser instances from the same machine. So inherently, UIPAB can have one task active at a time (it saves the states of all the tasks but keeps only one of them active at a time). The ActiveTaskID is used in the Load event handler of the WebFormView class in order to retrieve the state of the task.

The solution

With this behavior, UIPAB can have only one task active. What we need is some way to have multiple tasks active at a single instance. This leads us to an obvious conclusion that we cannot store the ActiveTaskID in session. We need to store it with the page. I thought of storing it in the ViewState of the page. But with all the navigations happening through Response.Redirect, it becomes impossible to store the TaskID in the viewstate. Then, I decided to put the taskID in the query string of the Page Request. I had to make two changes in the code provided by Microsoft to make this happen:

  • Change in WebFormView class: replace the default GetSessionMoniker method with the following:
  • private SessionMoniker GetSessionMoniker()
    {
        SessionMoniker sessionMoniker = null;
            try
            {
                sessionMoniker = SessionMoniker.GetFromSession(new Guid(Request.QueryString["taskId"]));
            }
            catch(Exception ex)
            {
                throw new UIPException(Resource.Exceptions.RES_ExceptionTaskNotFound);
            }
        return sessionMoniker;
    }
  • WebFormViewManager class: replace the ActivateView and RedirectToNextView methods with the following code:
  • public void ActivateView( string previousView, Guid taskId, string navGraph, string view )
    {
        //  create a session moniker
        SessionMoniker sessionMoniker = new SessionMoniker( navGraph, view, taskId);
        // store the moniker into the session, so the next view can get the task information
        sessionMoniker.StoreInSession();
                
        ViewSettings viewSettings = UIPConfiguration.Config.GetViewSettingsFromName( view ); 
        if( viewSettings == null )
            throw new UIPException(
                Resource.ResourceManager.FormatMessage(
                    Resource.Exceptions.RES_ExceptionViewConfigNotFound, view ) );
                
        HttpContext.Current.Session[WebFormView.CurrentTaskKey] = taskId.ToString();
        RedirectToNextView(previousView, viewSettings, taskId);
    }
    
    private void RedirectToNextView(string previousView, ViewSettings viewSettings, Guid taskId)
    {
        try
        {
            if (previousView == null)
                HttpContext.Current.Response.Redirect(
                    HttpContext.Current.Request.ApplicationPath + 
                    "/" + viewSettings.Type + 
                    "?taskID=" + 
                    taskId.ToString(), 
                    true);
            else
                HttpContext.Current.Response.Redirect(
                    HttpContext.Current.Request.ApplicationPath + 
                    "/" + viewSettings.Type 
                    + "?taskID=" + 
                    taskId.ToString(), 
                    false);
        }
        catch (System.Threading.ThreadAbortException) { }
    }

Using the code

Use the code as it is. You can directly start using the modified UIP code by downloading it. Or you can make the changes yourself to the UIPAB code downloaded from Microsoft’s website.

Note

The modifications done to UIPAB are solely by me and Microsoft has nothing to do with it. In case of any problems faced due to use of this code (specifically the features that were modified), Microsoft may not be held responsible for it. Commercial use of the code should be done only after thorough testing. I do not claim any responsibility for any erroneous behavior arising out of the use of the included code.

This article uses UIPAB 2.0. The same changes can be applied to UIPAB 1.x as well but I have not personally done so.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here