2016-11-15 49 views
1

我想让我的对话框与我的数据库一起工作。 如果我有我的对话是这样的:Microsoft Bot Framwork使用数据库结果

[Serializable] 
public class QuestionDialog : IDialog<object> 
{ 

    /// <summary> 
    /// Start our response 
    /// </summary> 
    /// <param name="context">The current context</param> 
    /// <returns></returns> 
    public async Task StartAsync(IDialogContext context) 
    { 

     // Move to the next method 
     context.Wait(StepOneAsync); 
    } 

    /// <summary> 
    /// When our message is recieved we execute this delegate 
    /// </summary> 
    /// <param name="context">The current context</param> 
    /// <param name="result">The result object</param> 
    /// <returns></returns> 
    private async Task StepOneAsync(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 

     // Get our activity 
     var activity = await result; 

     // Ask our first question 
     await context.PostAsync("hi"); 

     // Get our answer 
     context.Done(this); 
    } 
} 

一切正常,我让我的消息,如预期。然后,我把它改成这样:

[Serializable] 
public class QuestionDialog : IDialog<object> 
{ 

    // Private properties 
    private IList<QuestionGroup> _questionGroups; 

    /// <summary> 
    /// Start our response 
    /// </summary> 
    /// <param name="context">The current context</param> 
    /// <returns></returns> 
    public async Task StartAsync(IDialogContext context) 
    { 

     try 

     { 

      // Create our service 
      var questionGroupService = new QuestionGroupService(new UnitOfWork<DatabaseContext>()); 

      // Add our question groups 
      this._questionGroups = await questionGroupService.ListAllAsync(); 

      // Move to the next method 
      context.Wait(StepOneAsync); 
     } catch (Exception ex) 
     { 

     } 
    } 

    /// <summary> 
    /// When our message is recieved we execute this delegate 
    /// </summary> 
    /// <param name="context">The current context</param> 
    /// <param name="result">The result object</param> 
    /// <returns></returns> 
    private async Task StepOneAsync(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 

     // Get our activity 
     var activity = await result; 

     // Ask our first question 
     await context.PostAsync("hi"); 

     // Get our answer 
     context.Done(this); 
    } 
} 

而且它不会去的StepOneAsync方法。任何人都可以看到明显的事情,为什么这不起作用?

+0

QuestionGroup被标记为Serializable?如果你在对话框中持有引用,它们都需要是可序列化的(或者你需要明确地告诉对话框威胁它们不可序列化) –

+0

QuestionGroup没有标记为可序列化(它来自另一个我无法控制的项目) 。我如何将它标记为不可序列化? – r3plica

+0

尝试使用属性[NonSerialized]装饰字段。如果您需要跨不同消息使用该问题组,则可能会导致您将其引入功能中的其他问题,但会看到 –

回答

1

确保您的QestionGroup模型标记为可序列化。

如果你不能让它序列化,你还是希望自己的对话过程中引用它,你需要去与Bot Framework Technical FAQ的“How can I reference non-serializable services from my C# dialogs?”部分中描述的备选方案之一。

最简单的是在您的字段中使用NonSerialized属性。

或者,您可以尝试通过将反射序列化代理添加到Autofac容器来注册。在您的global.asax中,请尝试添加以下代码:

var builder = new ContainerBuilder(); 

builder.RegisterModule(new ReflectionSurrogateModule()); 

builder.Update(Conversation.Container); 
+0

我尝试过之前使用Autofac,但最终无法工作,所以我把它拿出来了。我使用https://github.com/Microsoft/BotBuilder/tree/master/CSharp/Samples/AlarmBot来帮助我构建我的模块。 – r3plica

+0

尝试此示例:https://github.com/Microsoft/BotBuilder-Samples/blob/master/CSharp/demo-ContosoFlowers/ContosoFlowers。这很容易。然而;尝试添加我发布在Global.asax中的那些行,而不是使用NonSerialized –

+0

另一种替代方法是将QuestionGroup对象映射到一个可以控制的对象,并且可以确保它可序列化 –