SDK Example 5 - Using the WorkSession

HotDocs templates may allow a user to complete multiple interviews and assemble multiple documents in a single session. In this example, you will use the HotDocs WorkSession to:

  • Repeatedly retrieve interviews
  • Complete interviews
  • Retrieve multiple assembled documents

Full source code for this example is available at the bottom of the page.

Example Source Code on GitHub

The SdkExample5Worksession example project is available on GitHub, in the HotDocs-Samples repository.

What is a WorkSession?

The WorkSession is a state machine that maintains a queue of Work Items waiting to be assembled. A Work Item represents either:

  • An Interview; or
  • An Assembled Document

Using the Work Session, you can get information about:

  • Completed Work Items
  • Pending Work Items
  • The Answer Collection used in the current Work Item

Using the Work Session, you can perform the following actions:

  • Display interviews for Work Items
  • Assemble documents for Work Items

For more information, see the WorkSession article in the HotDocs Open SDK help file.

1. Create a Visual Studio Project for Example 5

Before you start, create a new Console Application project for this example, named SdkExample5Worksession. You will gradually add code to this project until you have a working example. Remember to reference the HotDocs SDK DLLs at the beginning of the class.

2. Create a new WorkSession

Create a new method, CreateWorkSession, to return a new Work Session object:

private static WorkSession CreateWorkSession() {   }

To create the session, you need a Service object and a Template object. You can retrieve these using the CreateHotDocsService and CreateTemplate methods created in previous examples:

var service = CreateHotDocsService(); var template = CreateTemplate();

Using the newly-created Service and Template, create a new WorkSession:

var session = new WorkSession(service, template);

The WorkSession can now be returned for use elsewhere in the class. The final method looks like this:

private static WorkSession CreateWorkSession() {     var service = CreateHotDocsService();     var template = CreateTemplate();     var session = new WorkSession(service, template);     return session; }

3. Create the AssembleDocuments method

Next, you will add a new method that will create a WorkSession and use it to output assembled documents. First, create a new method, AssembleDocuments. The first line in this method is a call to the HotDocs SDK Utility method SetPersistentEncryptionKey.  This sets the key for encrypting WorkSession data.

private static void AssembleDocuments() {     Util.SetPersistentEncryptionKey("ExampleKey"); }

Add the CreateWorkSession method created in the step above to create the WorkSession:

private static void AssembleDocuments() {     var session = CreateWorkSession(); }

In the next step, you will expand this method, using the Work Session to access Work Items for processing.

4. Process the Work Items

Next, you will expand AssembleDocuments to process the current work item and output an assembled documents. This takes several steps, outlined below.

4.1 Check for Work Items to Process

First, add a new While loop to AssembleDocuments with a !session.IsCompleted condition:

while(!session.IsCompleted) {   }

This condition checks to see if all the Work Items in the current session have been processed (i.e. all WorkItems have IsCompleted property set to true and the CurrentWorkItem is null). Only while there are still Work Items in the session should you attempt to process them.

4.2 Retrieve the Current Work Item from the Session

After creating the Work Session, you must select a Work Item to process. As the Work Session is effectively a queue of Work Items, you need to select the Work Item next in line to be assembled. To retrieve this, access the CurrentWorkItem property of the Work Session object:

var currentWorkItem = session.CurrentWorkItem;

The currentWorkItem can then be used to retrieve an interview and assemble documents.

4.3 Process the Interviews for the Work Item

Inside the while loop, you now handle the interviews for the Work Item. A Work Item may contain multiple interviews. In HotDocs a single template can be used to assemble multiple other templates, each with their own interview. To handle this, the application must be able to process multiple interviews.

First, check that the current work item is the correct type of Work Item to process. As mention above, a Work Item can either be a Interview Work Item or an Assembled Document Work Item. At this stage, you are only interested in Interview Work Items. To check that browser interviews are processed only, you add the following check for the InterviewWorkItem type:

if (currentWorkItem is InterviewWorkItem) {   }

Within this condition, you can retrieve the interview HTML fragment from the session using the GetCurrentInterview method:

var interviewHtmlFragment = session.GetCurrentInterview();

At this stage, the interviewHtmlFragment should be passed to a View and displayed to the user.

Usually, when using a Work Session, answers would come from users filling out an interview, then posting back the answers when the interview is complete. For simplicity, retrieve the answers using the GetAnswers method from previous examples:

var answers = GetAnswers();

Now, use the Session FinishInterview method with the answers to mark the current interview as completed and update the AnswerCollection available in the WorkSession:

session.FinishInterview(answers);

4.4 Assemble the Documents for the Work Item

Once the Interview is complete the documents can assembled, using the WorkSession AssembleDocuments method:

var docs = session.AssembleDocuments("logref");

AssembleDocuments produces a collection of completed documents. Once the documents have been assembled, you can iterate through them and perform any additional processing required. In Example 1, this additional processing was saving the file to disk. Alternatively, it could be saving the file to a database.

foreach(var doc in docs) {     //Perform additional processing for each assembled document }

4.5 Completed AssembleDocuments Method

Once all the steps above are complete, the final AssembleDocuments method looks like this:

private static void AssembleDocuments() {     var session = CreateWorkSession();     while(!session.IsCompleted)     {         var currentWorkItem = session.CurrentWorkItem;         if(currentWorkItem is InterviewWorkItem)         {             var interviewHtmlFragment = session.GetCurrentInterview();             //Show interview to user, receive postback containing answers             var answers = GetAnswers(); session.FinishInterview(answers);         }         var docs = session.AssembleDocuments("logref");         foreach(var doc in docs)         {             //Perform additional processing for each assembled document         }     } }

Test

To test the WorkSession:

  1. Set the current project as the Startup Project (Right-click the SdkExample5Worksession project, select Startup Project from the drop-down menu).
  2. Set three breakpoints in Visual Studio:
    1. On var currentWorkItem = session.CurrentWorkItem in the AssembleDocuments method.
    2. On foreach(var docs in docs) in the AssembleDocuments method.
  3. Press F5 to run the project. The var currentWorkItem breakpoint is hit.
  4. Hover the mouse over the var session variable. This appears several lines above the current breakpoint. Not that the WorkSession contains two WorkItems. One is the InterviewWorkItem and one is the DocumentWorkItem.
  5. Hover the mouse over the session.CurrentWorkItem. The current work item is an InterviewWorkItem.
  6. Click Continue. The foreach breakpoint is hit.
  7. Hover the mouse over the docs collection in the foreach condition. One DOCX document has been assembled. At this stage, the session is completed, as there are no more interviews to process, and the document can be processed (for example, saved to disk).

Example Source Code (C#)

using System; using System.Collections.Generic; using System.IO; using HotDocs.Sdk; using HotDocs.Sdk.Server; using HotDocs.Sdk.Server.Local; namespace SdkExample5Worksession {     /// <summary>     /// This shows how to use a worksession to repeatedly retrieve interviews, complete them, and then retrieve the assembled documents     /// </summary>     internal class SdkExample5Worksession     {         private static void Main(string[] args)         {             AssembleDocuments();         }         private static void AssembleDocuments()         {

  Util.SetPersistentEncryptionKey("ExampleKey");

            var session = CreateWorkSession();                         while (!session.IsCompleted)             {                 var currentWorkItem = session.CurrentWorkItem;                 if (currentWorkItem is InterviewWorkItem)                 {                     var interviewHtmlFragment = session.GetCurrentInterview();                     //Show interview to user, receive postback containing answers                     var answers = GetAnswers();                     session.FinishInterview(answers);                 }                                  var docs = session.AssembleDocuments("logref");                 foreach (var doc in docs)                 {                     //Process each document as needed. For example, save document to disk, as in Example 2.                 }             }         }         private static WorkSession CreateWorkSession()         {             var service = CreateHotDocsService();             var template = CreateTemplate();             var session = new WorkSession(service, template);             return session;         }         private static Services CreateHotDocsService()         {             const string tempDirectoryPath = @"C:\temp\";             var service = new Services(tempDirectoryPath);             return service;         }         private static StringReader GetAnswers()         {             var answerCollection = CreateAnswerCollection();             var answerCollectionXml = answerCollection.XmlAnswers;             return new StringReader(answerCollectionXml);         }         private static AnswerCollection CreateAnswerCollection()         {             var answerCollection = new AnswerCollection();               //Text answers             var answer = answerCollection.CreateAnswer<TextValue>("TextExample-t");             answer.SetValue<TextValue>("World");               //Number answers             var numberAnswer = answerCollection.CreateAnswer<NumberValue>("NumberExample-n");             numberAnswer.SetValue<NumberValue>(123);               //Date answers             var dateAnswer = answerCollection.CreateAnswer<DateValue>("DateExample-d");             dateAnswer.SetValue<DateValue>(DateTime.Now);               //True/False answers             var trueFalseAnswer = answerCollection.CreateAnswer<TrueFalseValue>("TrueFalseExample-tf");             trueFalseAnswer.SetValue<TrueFalseValue>(true);               //Multiple choice answers                       var mcAnswer = answerCollection.CreateAnswer<MultipleChoiceValue>("MultipleChoiceExample-mc");             var multipleChoices = new List<string> { "Apple", "Orange" };             mcAnswer.SetValue(new MultipleChoiceValue(multipleChoices.ToArray()));               //Repeat answers             var repeatAnswer = answerCollection.CreateAnswer<TextValue>("NameRepeatExample-t");             repeatAnswer.SetValue<TextValue>("Steve", 0);             repeatAnswer.SetValue<TextValue>("Carol", 1);             repeatAnswer.SetValue<TextValue>("John", 2);             return answerCollection;         }         private static Template CreateTemplate()         {             const string packagePath = "HelloWorld.hdpkg";             string packageId = Guid.NewGuid().ToString();             var templateLocation = new PackagePathTemplateLocation(packageId, packagePath);             var template = new Template(templateLocation);             return template;         }     } }