You can use the API method of LUIS, instead of the dialog method.
Your code would be - RegisterPatientForm Class :
public enum Genders { none, Male, Female, Other };
[Serializable]
public class RegisterPatientForm
{
[Prompt("What is the patient`s name?")]
public string person_name;
[Prompt("What is the patients gender? {||}")]
public Genders gender;
[Prompt("What is the patients phone number?")]
[Pattern(@"(<Undefined control sequence>\d)?\s*\d{3}(-|\s*)\d{4}")]
public string phone_number;
[Prompt("What is the patients Date of birth?")]
public DateTime DOB;
[Prompt("What is the patients CNIC number?")]
public string cnic;
public static IForm<RegisterPatientForm> BuildForm()
{
OnCompletionAsyncDelegate<RegisterPatientForm> processHotelsSearch = async (context, state) =>
{
await context.PostAsync($"Patient {state.person_name} registered");
};
return new FormBuilder<RegisterPatientForm>()
.Field(nameof(person_name),
validate: async (state, response) =>
{
var result = new ValidateResult { IsValid = true, Value = response };
//Query LUIS and get the response
LUISOutput LuisOutput = await GetIntentAndEntitiesFromLUIS((string)response);
//Now you have the intents and entities in LuisOutput object
//See if your entity is present in the intent and then retrieve the value
if (Array.Find(LuisOutput.intents, intent => intent.Intent == "GetName") != null)
{
LUISEntity LuisEntity = Array.Find(LuisOutput.entities, element => element.Type == "name");
if (LuisEntity != null)
{
//Store the found response in resut
result.Value = LuisEntity.Entity;
}
else
{
//Name not found in the response
result.IsValid = false;
}
}
else
{
//Intent not found
result.IsValid = false;
}
return result;
})
.Field(nameof(gender))
.Field(nameof(phone_number))
.Field(nameof(DOB))
.Field(nameof(cnic))
.OnCompletion(processHotelsSearch)
.Build();
}
public static async Task<LUISOutput> GetIntentAndEntitiesFromLUIS(string Query)
{
Query = Uri.EscapeDataString(Query);
LUISOutput luisData = new LUISOutput();
try
{
using (HttpClient client = new HttpClient())
{
string RequestURI = WebConfigurationManager.AppSettings["LuisModelEndpoint"] + Query;
HttpResponseMessage msg = await client.GetAsync(RequestURI);
if (msg.IsSuccessStatusCode)
{
var JsonDataResponse = await msg.Content.ReadAsStringAsync();
luisData = JsonConvert.DeserializeObject<LUISOutput>(JsonDataResponse);
}
}
}
catch (Exception ex)
{
}
return luisData;
}
}
Here GetIntentAndEntitiesFromLUIS
method does the querying to LUIS using the endpoint exposed by your Luis app. Add the endpoint to your Web.config with key LuisModelEndpoint
Find your luis endpoint by going to Publish tab in your luis app
Your web.config would look like this
<appSettings>
<!-- update these with your BotId, Microsoft App Id and your Microsoft App Password-->
<add key="BotId" value="YourBotId" />
<add key="MicrosoftAppId" value="" />
<add key="MicrosoftAppPassword" value="" />
<add key="LuisModelEndpoint" value="https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/YOUR_MODEL_ID?subscription-key=YOUR_SUBSCRIPTION_KEY&verbose=true&timezoneOffset=0&q="/>
</appSettings>
I have created a LUISOutput class to deserialize the response:
public class LUISOutput
{
public string query { get; set; }
public LUISIntent[] intents { get; set; }
public LUISEntity[] entities { get; set; }
}
public class LUISEntity
{
public string Entity { get; set; }
public string Type { get; set; }
public string StartIndex { get; set; }
public string EndIndex { get; set; }
public float Score { get; set; }
}
public class LUISIntent
{
public string Intent { get; set; }
public float Score { get; set; }
}
Emulator Response
FormFlow
may not really be the best solution if you want to do some custom treatments – Nicolas R