Botbuilder自适应对话预览版:如何从TextInput的Property取信息存入SQL
如何从Bot Builder自适应对话的TextInput控件Property中获取用户信息并存入SQL
首先得给你掰明白:TextInput的Property属性本质就是对话状态存储的路径(你示例里用的user.userProfile{question.Id}是绑定到UserState下的嵌套对象)。要拿到这个值,核心就是从对应的状态容器里读取这个路径指向的数据。
我给你分步骤拆解,附带实用代码示例:
1. 先确保UserState配置到位
因为你用的是user.开头的路径,属于用户级别的持久化状态,所以得先保证Bot已经配置了UserState。一般在Startup或者Program.cs里会有类似配置:
// 注册UserState服务 services.AddSingleton<UserState>(); // 注册状态访问器,方便后续读取 services.AddSingleton<BotStateAccessors>(sp => { var userState = sp.GetService<UserState>(); return new BotStateAccessors { // 这里的"userProfile"是状态存储的键名,和你Property里的路径对应 UserProfileAccessor = userState.CreateProperty<UserProfile>("userProfile") }; });
这里的UserProfile建议用字典来存储动态字段(毕竟你的question.Id是变化的),比固定字段灵活:
public class UserProfile { public Dictionary<string, string> FormResponses { get; set; } = new Dictionary<string, string>(); }
(如果用字典的话,你的Property路径可以改成user.userProfile.FormResponses[${question.Id}],更规范)
2. 在对话中读取TextInput绑定的值
用户完成输入后,值会自动存入UserState对应的路径里。你可以在对话的后续步骤(比如自定义CodeAction)里读取:
方法一:通过状态访问器读取完整对象
// 从TurnState中获取UserState实例 var userState = turnContext.TurnState.Get<UserState>(); // 获取之前注册的状态访问器 var userProfileAccessor = userState.CreateProperty<UserProfile>("userProfile"); // 拿到完整的用户配置文件对象 var userProfile = await userProfileAccessor.GetAsync(turnContext, () => new UserProfile()); // 根据question.Id取出对应的值,比如question.Id是"PhoneNumber" var userInput = userProfile.FormResponses[question.Id];
方法二:用StatePath解析动态路径(适合你这种拼接路径的场景)
如果你的Property是动态拼接的(比如"user.userProfile" + question.Id),可以用StatePath直接解析路径取值:
using Microsoft.Bot.Builder.Dialogs.Adaptive; // 构建完整的状态路径字符串 var propertyPath = $"user.userProfile.{question.Id}"; // 解析路径 var statePath = new StatePath(propertyPath); // 从TurnContext的State中直接取值 var userInput = statePath.GetValue(turnContext.State);
3. 把值存入SQL数据库
拿到值之后,就用常规的数据库操作就行,比如用Entity Framework的示例:
// 假设你有自己的DbContext using (var dbContext = new YourAppDbContext()) { var userRecord = new UserFormRecord { UserId = turnContext.Activity.From.Id, FieldKey = question.Id, FieldValue = userInput.ToString(), CreatedTime = DateTime.UtcNow }; dbContext.UserFormRecords.Add(userRecord); await dbContext.SaveChangesAsync(); }
几个关键提醒
- 路径一定要和状态对象的结构完全匹配,不然会读不到值
- 记得在合适的时机调用
await userState.SaveChangesAsync(turnContext);,不然状态里的值不会持久化 - 如果question.Id是动态的,用字典存储比固定字段更省心,不用每次加新字段都改实体类
内容的提问来源于stack exchange,提问作者Rocco
相关产品推荐
相关产品推荐

