Я использую Luis, чтобы определить, запускает ли пользователь поток с некоторыми объектами, например: он может сказать «Отчет» или «Я хочу сообщить в Лондоне» или "Я хочу сообщить о месте x в Лондоне"
[LuisIntent("Report")]
public async Task ReportCompleteIntent(IDialogContext context, LuisResult result)
{
EntityRecommendation location;
EntityRecommendation POS;
result.TryFindEntity("Weather.Location", out location);
result.TryFindEntity("POS", out POS);
//I tried with passing entities (it doesn't recognize the entities in formBuild)
context.Call(Chain.From(() => new FormDialog<OutOfStockReport>(new OutOfStockReport(), buildForm: OutOfStockReport.BuildForm, options: FormOptions.PromptInStart, entities: result.Entities)), OOSDialogComplete);
//Also tried prepopulating the state
context.Call(Chain.From(() => new FormDialog<OutOfStockReport>(new OutOfStockReport() { LocalizationId = location?.Entity }, buildForm: OutOfStockReport.BuildForm, options: FormOptions.PromptInStart)), OOSDialogComplete);
}
Это класс и форма сборки:
[Serializable]
[Template(TemplateUsage.NavigationFormat, "{&}")]
public class OutOfStockReport
{
public string LocalizationId;
public string PositionId;
public static IForm<OutOfStockReport> BuildForm()
{
return FormBuilderHelper.CreateCustomForm<OutOfStockReport>()
.Message("Welcome!")
.Field(new FieldReflector<OutOfStockReport>(nameof(LocalizationId))
.SetType(null)
.SetActive(hasLocation)
.SetDefine(async (state, field) =>
{
var cities = new City().GetCities();
foreach (var option in cities)
{
var description = new DescribeAttribute($"{option.Name}", message: $"{option.Name}", title: $"{option.Name}");
field.AddDescription(option.Id, description);
field.AddTerms(option.Id, Language.GenerateTerms(Language.CamelCase(option.Name), 3));
}
return true;
})
.SetValidate(async (state, response) =>
{
state.PositionId = null;
var result = new ValidateResult { IsValid = true, Value = response };
return result;
}))
.Field(new FieldReflector<OutOfStockReport>(nameof(PositionId))
.SetType(null)
.SetActive((state) => !string.IsNullOrEmpty(state.LocalizationId))
.SetDefine(async (state, field) =>
{
field.RemoveValues();
var localizedOptions = new Position().GetPositions(state.LocalizationId);
foreach (var option in localizedOptions)
{
var description = new DescribeAttribute($"{option.Name}", message: $"{option.Name}", title: $"{option.Name}");
field.AddDescription(option.Id, description);
field.AddTerms(option.Id, Language.GenerateTerms(Language.CamelCase($"{option.Id} {option.Name} {option.Direction}"), 3));
}
return true;
}))
.AddRemainingFields()
.Confirm("Are you sure of your selection?{||}")
.OnCompletion(async (context, state) => await context.PostAsync($"Thanks, the task is complete."))
.Build();
При добавлении ActiveDelegate hasLocation я могу контролировать, должно ли отображаться поле LocationId или нет. Это работает, но после этого бот прерывается с сообщением «Извините, в коде моего бота возникла проблема».
РЕДАКТИРОВАТЬ
Классы, которые используются в форме:
Базовая модель класса
public class BaseModel
{
public string Id{ get; set; }
}
Класс Город
public class City : BaseModel
{
public string Name { get; set; }
}
Позиция в классе
public class Position : BaseModel
{
public string Name { get; set; }
public string Direction { get; set; }
public string CityId { get; set; }
}