Jason Evans
Jason Evans

Reputation: 29186

`Feedback` text not shown in bot conversation

My formflow dialog contains a field with custom validation applied...

 var form = builder
    .Field(new FieldReflector<CarValuationDialog>(nameof(UserName))
    .SetActive(state => string.IsNullOrEmpty(state.UserName)))
    .Field(new FieldReflector<CarValuationDialog>(nameof(ValuationOption))
        .SetPrompt(new PromptAttribute($"Hello {{UserName}}.<br /><br />Are you looking to get an price estimate for a car you’re selling, or for a car you’re looking to buy? {{||}}")))
    .Field(new FieldReflector<CarValuationDialog>(nameof(RegistrationNumber))
        .SetDefine(RegistrationNumberDefinitionMethod))
    .Field(new FieldReflector<CarValuationDialog>(nameof(Mileage))
                    .SetValidate(async (state, value) =>
                        {
                            var result = new ValidateResult { IsValid = true, Value = value };

                            if (int.TryParse(value.ToString(), out int mileage))
                            {
                                result.IsValid = true;
                            }
                            else
                            {
                                result.Feedback = "That isn't valid number. Can you enter it again please?";
                                result.IsValid = false;
                            }

                            return await Task.FromResult(result);
                        }))
    .Field(nameof(PreviousOwnerOption),
        active: carValuationDialog => carValuationDialog.ValuationOption == ValuationOptions.LookingToSell)
    .Field(nameof(ServiceHistoryOption),
        active: carValuationDialog => carValuationDialog.ValuationOption == ValuationOptions.LookingToSell)
    .Confirm(Confirmation)
    .OnCompletion(GetValuationAndDisplaySummaryToUser);

When SetValidate() executes, and the given mileage value is not an int, the result.Feedback = ... line is executed. However, instead of seeing the message "That isn't a valid mileage value. Can you enter it again please?" I see this...

enter image description here

Full discolsure, I do have the following attribute declared on the dialog class

[Template(TemplateUsage.NotUnderstood, "Sorry, I don't understand '{0}'.")]

but I thought the result.Feedback text would be shown to the user in this case? Not using the Template[] results in the following text displayed when the user enters an invalid mileage...

"d" is not a car mileage option.

Which looks rubbish, and is why I used the Template[] override.

Upvotes: 3

Views: 96

Answers (1)

D4RKCIDE
D4RKCIDE

Reputation: 3426

EDIT I was able to accomplish this by applying templates to the fields themselves for validation. This should be the exact behavior you are looking for. Note that I did not do extensive testing, I just wanted to get the general idea working. Heres the code I used:

[Serializable]
public class SandwichOrder
{
    //public PreviousOwnerOptions Options;
    [Template(TemplateUsage.NotUnderstood, "Sorry, I don't understand '{0}'.")]
    [Prompt("What is the {&}?")]
    public int Mileage;

    [Template(TemplateUsage.NotUnderstood, "Sorry, This is not valid '{0}'.")]
    [Prompt("How many {&}?")]
    public int Days;


    public static IForm<SandwichOrder> BuildForm()
    {
        var form = new FormBuilder<SandwichOrder>()
            .Field(new FieldReflector<SandwichOrder>(nameof(Mileage))
                .SetValidate(async (state, value) =>
                {
                    var result = new ValidateResult {IsValid = true, Value = value};

                    if (int.TryParse(value.ToString(), out int mileage))
                    {
                        result.IsValid = true;
                    }
                    else
                    {
                        result.IsValid = false;
                    }

                    return await Task.FromResult(result);
                }))
            .Field(new FieldReflector<SandwichOrder>(nameof(Days))
            .SetValidate(async (state, value) =>
            {
                var result = new ValidateResult { IsValid = true, Value = value };

                if (int.TryParse(value.ToString(), out int days))
                {
                    result.IsValid = true;
                }
                else
                {
                    result.IsValid = false;
                }

                return await Task.FromResult(result);
            }));
        return form.Build();
    }
}

This produced this result:

enter image description here

Upvotes: 4

Related Questions