I'm currently looking for a way to dynamically create a FormDialog
from values predefined in the database. In other words, my field types, prompts and settings are all stored in a database, and what I'm trying to achieve is reading those settings and building the appropriate form dynamically.
What I tried so far is something similar to the following. Suppose I have a form with a Name (string
) and an Age (int
) field (FieldDefinition
is a class I created to store the parameters of a field, assuming they are fetched from the database) (The code is stripped just to illustrate the idea):
public static IForm<dynamic> BuildForm()
{
string FormMessage = "Welcome to demo contact form!";
string CompletionMessage = "Thank your for your info. Our team will contact you as soon as possible.";
var fields = new List<FieldDefinition>()
{
new FieldDefinition()
{
Name = "Name",
FieldType = typeof(string),
Prompts = new string[] { "What's your name?", "Please input your name" }
},
new FieldDefinition()
{
Name = "Age",
FieldType = typeof(int),
Prompts = new string[] { "What's your age?", "How old are you?" }
}
};
var builder = new FormBuilder<dynamic>();
builder.Message(FormMessage);
foreach (var f in fields)
{
builder.Field(
new FieldReflector<dynamic>(f.Name)
.SetType(f.FieldType)
);
}
builder.AddRemainingFields()
.OnCompletion(async (context, order) => {
var message = context.MakeMessage();
message.Text = CompletionMessage;
await context.PostAsync(message);
});
return builder.Build();
}
So here's the problems:
I thought I could use a dynamic
type. But a method cannot return a dynamic
object as it is determined at run-time. Therefore, I got an error when I tried building the form using the following:
dynamic values; var form = new FormDialog<dynamic>(values, ContactForm.BuildForm, FormOptions.PromptInStart, null);`
I need to create the properties of the object dynamically, therefore I looked for a way to create a Type
on runtime. I ended up with something called TypeBuilder
but I was a bit skeptical if it could solve my problem or not.
Therefore, I guess the ultimate start is by using the FieldReflector
but I have no idea how to achieve this. I'm looking for something similar to the above but that does actually work.
Have you looked at FormBuilderJson? You could dynamically construct the .json string, and build the form at runtime:
public static IForm<JObject> BuildJsonForm()
{
string fromFlowJson = GetFormFlowJson();
return new FormBuilderJson(schema)
.AddRemainingFields()
.Build();
}
See here for more information: https://learn.microsoft.com/en-us/azure/bot-service/dotnet/bot-builder-dotnet-formflow-json-schema?view=azure-bot-service-3.0