SDK Example 2 - Create an Answer Collection
In the previous example, you used a static answer XML string to populate the assembled document with answer values. The following example demonstrates how you can create a custom answer collection for populating answers in the assembled document.
In this example you will:
- Create a new CreateAnswerCollection method.
- Use the AnswerCollection to create HotDocs answers.
- Update the GetAnswers method from Example 1 to retrieve answer XML from the AnswerCollection.
Full source code for this example is available at the bottom of the page.
Example Source Code on GitHub
The SdkExample2AnswerCollection example project is available on GitHub, in the HotDocs-Samples repository.
HotDocs Answers Overview
HotDocs Answers are representations of data that HotDocs merges into the final document during the assembly process. Each answer can be one of five types:
- Text
- Number
- Date
- True/False
- Multiple Choice
When interacting with answers in the HotDocs Open SDK, each Answer is part of an AnswerCollection, a collection of all answer objects used by the current assembly.
1. Create a Visual Studio Project for Example 2
Before you start, create a new Console Application project for this example, named SdkExample2AnswerCollection. 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.
1. Create a new CreateAnswerCollection method
1.2 Create the method
First, create a new CreateAnswerCollection method. This will return an AnswerCollection object.
private static AnswerCollection CreateAnswerCollection()
{
}
You will expand CreateAnswerCollection over the next steps.
1.2 Create the Answer Collection
Create a new AnswerCollection object:
var answerCollection = new AnswerCollection();
Once you have created the AnswerCollection, you can begin to add new answers to the collection.
1.3 Use the AnswerCollection object to create new answers
HotDocs has five different answer types, as explained above. In this example, you will create data for all five answer types and add them to the answer collection.
1.3.1 Using CreateAnswer
To create a new text answer and add it to the AnswerCollection, use the AnswerCollection's CreateAnswer method. The method looks as follows, with placeholder values in red:
var answer = answerCollection.CreateAnswer<Type>(answer_name);
Note the following:
- The data passed into CreateAnswer (above, "answer_name") is the name of the answer variable. The name of each answer you create must not be a duplicate of another answer in the AnswerCollection.
- The Type parameter in CreateAnswer corresponds to the type of answer being created. The types are:
- TextValue – a text answer
- NumberValue – a number answer
- DateValue – a date answer
- TrueFalseValue – a true/false value
- MultipleChoiceValue – a multiple choice value
Relationship between HotDocs Answer Variables and HotDocs Answers in the AnswerCollection
There is a distinction to be made between HotDocs Answer Variables and HotDocs Answers in the AnswerCollection:
- HotDocs Answer Variables – created when developing a template. Used as placeholders in the template into which HotDocs inserts data on document assembly.
- HotDocs Answers in AnswerCollection – created when building an answer collection. This contains the data HotDocs inserts into the placeholder Answer Variables in the template.
In order for the HotDocs Answers in the AnswerCollection to replace the placeholders, they must have the same name. For example, if there is a text variable EmployeeName-t in the template, the AnswerCollection answer name must match, i.e.
var answer = answerCollection.CreateAnswer<TextValue>("EmployeeName-t");
1.3.2 Text Answers
To create a new text answer, add the following to the CreateAnswerCollection method:
var answer = answerCollection.CreateAnswer<TextValue>("TextExample-t");
To set a value for the newly-created text answer, use the SetValue method:
answer.SetValue<TextValue>("World");
The data passed into SetValue is always the answer value you wish to be set for the answer. The data passed in should conform to the type of answer you are creating, i.e. a string for a text variable, a number for a number variable, and so on.
Each type of variable uses the same process to create the answer and set a value for that answer:
- Use the CreateAnswer method Answer Collection object to create a new answer
- Use SetAnswer on the Answer to add a value to the answer
We will create an answer for all of the other answer types in the following steps.
1.3.3 Number Answers
Create a Number answer named NumberExample-n:
var numberAnswer = answerCollection.CreateAnswer<NumberValue>("NumberExample-n");
Set the value of the answer to 123:
numberAnswer.SetValue<NumberValue>(123);
1.3.4 Date Answers
Create a Date answer named DateExample-d:
var dateAnswer = answerCollection.CreateAnswer<DateValue>("DateExample-d");
Set the value of the answer using the .Net Property, DateTime.Now:
dateAnswer.SetValue<DateValue>(DateTime.Now);
HotDocs will discard the Time portion of DateTime.Now and only use the Date to set the value of the answer.
1.3.5 True/False Answers
Create a True/False answer named TrueFalseExample-tf:
var trueFalseAnswer = answerCollection.CreateAnswer<TrueFalseValue>("TrueFalseExample-tf");
Set the value of the answer using a boolean value, either true or false:
trueFalseAnswer.SetValue<TrueFalseValue>(true);
1.3.6 Multiple Choice Answers
Create a Multiple Choice answer named MultipleChoiceExample-mc:
var mcAnswer = answerCollection.CreateAnswer<MultipleChoiceValue>("MultipleChoiceExample-mc");
Multiple choice answers use an array to create multiple answer values. In the case, create a string array to hold the answers:
var multipleChoices = new string[] { "Apple", "Orange"
};
When passing it to create a new answer value, you must pass a new MultipleChoiceValue into SetValue, with the new array as a parameter:
mcAnswer.SetValue(new MultipleChoiceValue(multipleChoices.ToArray()));
1.4 Using Repeat Answers
Repeat answers are structures in HotDocs where a single answer may contain multiple indexed values. Any of the five answer types detailed above may be used in a repeat answer structure.
In the example below, there is a text-type answer ("NameRepeatExample-t") that contains multiple answer values, each with their own identifying index value.
var repeatAnswer = answerCollection.CreateAnswer<TextValue>("NameRepeatExample-t");
repeatAnswer.SetValue<TextValue>("Steve",
0);
repeatAnswer.SetValue<TextValue>("Carol",
1);
repeatAnswer.SetValue<TextValue>("John",
2);
This can be used in a document where the same type of information is to be repeated multiple times, e.g. in a list. For a full explanation of repeat structures, see the Values and Repeated Answers in HotDocs section in the HotDocs Answer Files Overview.
2. Modify the GetAnswers method to use AnswerCollection
In the previous example, the GetAnswers method returned a static string of XML answers. For this example, you need to use the answer collection created above, retrieve xml answers from the collection, and return the XML as a StringReader.
First, retrieve the answer collection, using the CreateAnswerCollection method created above:
var answerCollection = CreateAnswerCollection();
Next, retrieve the answer XML from the AnswerCollection. We can do this by accessing the XmlAnswer property of the AnswerCollection:
var answerCollectionXml = answerCollection.XmlAnswers;
Finally, return the XML answers as a StringReader, so it can be used by the AssembleDocument method later in the class:
return new StringReader(answerCollectionXml);
The final method looks like this:
private static StringReader GetAnswers()
{
var
answerCollection = CreateAnswerCollection();
var
answerCollectionXml = answerCollection.XmlAnswers;
return
new StringReader(answerCollectionXml);
}
3. Test
To test assembling a document using the answer collection:
- Set the current project as the Startup Project (Right-click the Example2 project in Visual Studio and select Startup Project from the drop-down menu)
- Press F5 to run the Project. The console opens and closes.
- Open the newly-created output document (C:\temp\output.docx). The answers from the answer collection have been merged into the completed document.
Example Source Code (C#)
using System;
using
System.Collections.Generic;
using
System.IO;
using
HotDocs.Sdk;
using
HotDocs.Sdk.Server;
using
Services = HotDocs.Sdk.Server.Local.Services;
namespace SdkExample2AnswerCollection
{
///
<summary>
///
This demonstrates creating an answer collection containing various answer
types and then reading out the resulting answer XML
///
</summary>
internal
class Example2
{
private
static void Main(string[] args)
{
AssembleDocument();
}
private
static void AssembleDocument()
{
var
assembledDocumentResult = CreateAssembleDocumentResult();
using
(var fileStream = File.Create(@"C:\temp\output" + assembledDocumentResult.Document.FileExtension))
{
assembledDocumentResult.Document.Content.CopyTo(fileStream);
}
}
private
static AssembleDocumentResult CreateAssembleDocumentResult()
{
var
template = CreateTemplate();
var
answers = GetAnswers();
var
assembleDocumentSettings = new AssembleDocumentSettings();
var
service = CreateHotDocsService();
var
assembledDocumentResult = service.AssembleDocument(template, answers,
assembleDocumentSettings, "Example Assemble Document Log Text");
return
assembledDocumentResult;
}
private
static Services CreateHotDocsService()
{
const
string tempDirectoryPath = @"C:\temp\";
var
service = new Services(tempDirectoryPath);
return
service;
}
private
static Template CreateTemplate()
{
const
string packagePath = @"C:\temp\HelloWorld.hdpkg";
var
packageId = Guid.NewGuid().ToString();
var
templateLocation = new PackagePathTemplateLocation(packageId, packagePath);
var
template = new Template(templateLocation);
return
template;
}
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 string[] { "Apple", "Orange"
};
mcAnswer.SetValue(new
MultipleChoiceValue(multipleChoices));
//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;
}
}
}