C# 如何解决FormFlow中值之间的依赖关系冲突
我正在使用带有FormFlow的MicrosoftBot框架让用户填写表单。 假设我的表单有两个字段:C# 如何解决FormFlow中值之间的依赖关系冲突,c#,botframework,formflow,C#,Botframework,Formflow,我正在使用带有FormFlow的MicrosoftBot框架让用户填写表单。 假设我的表单有两个字段: 国家 城市 所以我有两个枚举: public enum Country { France, Germany } public enum City { Paris, Berlin } 田野城市总是依赖田野国家,因为一个城市属于一个国家。 这意味着用户只能填写法国+巴黎或德国+柏林 我的表格: public class LocationForm { [Prompt(
- 国家
- 城市
public enum Country {
France, Germany
}
public enum City {
Paris, Berlin
}
田野城市总是依赖田野国家,因为一个城市属于一个国家。
这意味着用户只能填写法国+巴黎或德国+柏林
我的表格:
public class LocationForm
{
[Prompt("Which country? {||}")]
public Country? Country;
[Prompt("Which city? {||}")]
public City? City;
}
我的建筑商:
private static IForm<LocationForm> BuildLocationForm()
{
return new FormBuilder<LocationForm>()
.Field(nameof(Country))
.Field(new FieldReflector<LocationForm>(nameof(LocationForm.City))
.SetDefine(async (state, field) =>
{
switch (state.Country)
{
case Country.France:
field.RemoveValue(City.Berlin);
break;
case Country.Germany:
field.RemoveValue(City.Paris);
break;
}
return true;
})
.Confirm(async (state) =>
new PromptAttribute(
"You selected {Country} and {City}, is that correct? {||}"))
.Build();
}
private静态格式BuildLocationForm()
{
返回新的FormBuilder()
.字段(名称(国家))
.Field(新FieldReflector(名称(位置形式.城市))
.SetDefine(异步(状态、字段)=>
{
开关(州、国家)
{
案例国家:法国:
field.RemoveValue(城市柏林);
打破
案例国家:德国:
field.RemoveValue(城市,巴黎);
打破
}
返回true;
})
.确认(异步(状态)=>
新PrompAttribute(
“您选择了{Country}和{City},对吗?{|}”))
.Build();
}
我不知道RemoveValue在这里的用法是否正确,感觉有点被黑客攻击了,但到目前为止它仍然有效
用户第一次填写表单时,一切正常,用户只能根据之前选择的国家选择巴黎或柏林。
但是,当用户用否回答确认问题时,可以更改国家或城市。
然后,当用户将国家从法国更改为德国时,FormFlow将询问:
你选择了德国和巴黎,对吗
这显然是不正确的,但是仍然可以回答是
我想实现的是,无论何时通过确认对话框更改国家,用户都必须根据国家字段中的更改更改城市选择
我在玩弄SetNext方法,但我想不出任何有用的东西
我走错方向了吗?
如果没有对整个FormFlow实现进行黑客攻击,这是可能的吗
我将感谢任何帮助
提前谢谢
更新(附加信息):我尝试了Microsoft Find提供的三明治机器人示例,它似乎有相同的(错误)行为。
您可以额外获得一份(免费饼干/饮料)订购一英尺长的三明治时。确认后将长度更改为六英寸,您仍然有多余的,但只需支付六英寸。您可以做的是,在
国家/地区字段内,验证以前的选择和新选择是否相同;如果不清楚城市的值,则会再次提示该城市。
同时将您的城市类型更改为string
,这样您就可以根据选择的country
动态加载值,而不是使用field.RemoveValue()
(尽管这不是一个坏方法)
因此,代码应该是:
[Serializable]
public class LocationForm
{
[Prompt("Which country? {||}")]
public Country? country;
[Prompt("Which city? {||}")]
public string city;
public static IForm<LocationForm> BuildLocationForm()
{
return new FormBuilder<LocationForm>()
.Field(new FieldReflector<LocationForm>(nameof(country))
.SetValidate(async (state, response) =>
{
var result = new ValidateResult { IsValid = true, Value = response };
//Validation to check if the current country and previous selected country are same so that user is not prompted again for city
if (state.country.ToString() != response.ToString())
state.city = String.Empty;
return result;
}))
.Field(new FieldReflector<LocationForm>(nameof(city))
//To get buttons SetType(null)
.SetType(null)
.SetDefine(async (state, field) =>
{
//Any previous value before the confirm should be cleared in case selection is changed for country
field.RemoveValues();
switch (state.country)
{
case Country.France:
field
.AddDescription(nameof(City.Berlin), nameof(City.Berlin))
.AddTerms(nameof(City.Berlin), nameof(City.Berlin));
//Add more description and terms if any
break;
case Country.Germany:
field
.AddDescription(nameof(City.Paris), nameof(City.Paris))
.AddTerms(nameof(City.Paris), nameof(City.Paris));
//Add more description and terms if any
break;
}
return true;
}))
.AddRemainingFields()
.Confirm(async (state) =>
{
return new PromptAttribute($"You selected {state.country} and {state.city}, is that correct?" + "{||}");
})
.Build();
}
}
[Serializable]
public enum Country
{
France, Germany
}
[Serializable]
public enum City
{
Paris, Berlin
}
[可序列化]
公务舱位置表
{
[提示(“哪个国家?{|}”)]
公共国家?国家;
[提示(“哪个城市?{|}”)]
公共字符串城市;
公共静态表单BuildLocationForm()
{
返回新的FormBuilder()
.Field(新FieldReflector(名称(国家))
.SetValidate(异步(状态、响应)=>
{
var result=newvalidateResult{IsValid=true,Value=response};
//验证以检查当前国家/地区和以前选择的国家/地区是否相同,从而不会再次提示用户输入城市
if(state.country.ToString()!=response.ToString())
state.city=String.Empty;
返回结果;
}))
.Field(新FieldReflector(名称(城市))
//获取按钮的步骤SetType(null)
.SetType(空)
.SetDefine(异步(状态、字段)=>
{
//如果更改了国家/地区的选择,则应清除确认之前的任何值
field.RemoveValues();
开关(州、国家)
{
案例国家:法国:
领域
.AddDescription(name of(City.Berlin),name of(City.Berlin))
.AddTerms(name of(City.Berlin),name of(City.Berlin));
//添加更多说明和术语(如有)
打破
案例国家:德国:
领域
.AddDescription(name of(City.Paris),name of(City.Paris))
.AddTerms(name of(City.Paris),name of(City.Paris));
//添加更多说明和术语(如有)
打破
}
返回true;
}))
.AddRemainingFields()
.确认(异步(状态)=>
{
返回新的prompattribute($“您选择了{state.country}和{state.city},对吗?”+“{|}”);
})
.Build();
}
}
[可序列化]
公共枚举国家
{
法国、德国
}
[可序列化]
公共城市
{
巴黎,柏林
}
现在您有了预期的行为。如果国家/地区发生更改,城市将再次提示选择。如果用户说否
进行确认,并且没有更改国家/地区,则选择上一个选择