botframework-sdk: [.Net SDK, Azure Function] MissingMethodException thrown when accessing Microsoft.Bot.Builder.Dialogs.Conversation.Container
Bot Info
- SDK Platform: .NET
- SDK Version: 3.15 (happens on 3.12.2.4 too)
- Active Channels: bot emulator, WebChat, Direct Line
- Deployment Environment: local development with Emulator
Issue Description
My bot is based on Azure Functions. I need to access state data from a Function which is triggered by a queue, in order to push a pro-active message to the user. So I implemented code from https://stackoverflow.com/questions/46085614/, but when I tried to access the implementing method, I received a System.MissingMethodException: Method not found: 'Autofac.IContainer Microsoft.Bot.Builder.Dialogs.Conversation.get_Container()'.
exception.
Code Example
(again, this is an Azure Function)
[FunctionName("PasswordResponseFunction")]
public static async Task Run([ServiceBusTrigger("password-response", AccessRights.Listen, Connection = "ServiceBusReceivePasswordResponseConnection")]BrokeredMessage message, TraceWriter log)
{
try
{
Stream body = message.GetBody<Stream>();
BinaryFormatter formatter = new BinaryFormatter();
String password = formatter.Deserialize(body) as String;
log.Info($"C# ServiceBus queue trigger function processed message: { password }");
IMessageActivity messageActivity = Activity.CreateMessageActivity();
// Set some messageActivity properties here
await SetPrivateConversationDataAsync(messageActivity, "password", password); // <-Exception thrown at this point
ConnectorClient client = new ConnectorClient(new Uri(ActivityDataEntity.ServiceUrl));
Activity activity = (Activity)messageActivity;
await client.Conversations.SendToConversationAsync(activity);
}
catch (Exception ex)
{
log.Error(ex.Message, ex);
}
}
private static async Task SetPrivateConversationDataAsync<T>(IMessageActivity messageActivity, String key, T value)
{
using (ILifetimeScope scope = DialogModule.BeginLifetimeScope(Conversation.Container, messageActivity)) //System.MissingMethodException
{
IBotDataStore<BotData> botDataStore = scope.Resolve<IBotDataStore<BotData>>();
Address address = Address.FromActivity(messageActivity);
BotData privateConversationData = await botDataStore.LoadAsync(address, BotStoreType.BotPrivateConversationData, CancellationToken.None);
privateConversationData.SetProperty(key, value);
await botDataStore.SaveAsync(address, BotStoreType.BotPrivateConversationData, privateConversationData,
CancellationToken.None);
await botDataStore.FlushAsync(address, CancellationToken.None);
}
}
Reproduction Steps
- Create a Class Library C# Function Bot
- Create a C# Function Bot
- Create an Azure Function with HTTP Trigger project in Visual Studio 2017
- Copy the code from the generated Function Bot to your Function
- Delete the C# Script bot from the Azure Portal
- Deploy the function you created
- Add a call to
Conversation.Container
, such asIContainer c = Conversation.Container;
to the function - make a call to the bot from Bot Emulator
Expected Behavior
Get an IContainer
Actual Results
Exception as described.
Stack Trace:
Varonis.Bot.Application.PasswordResponseFunction.<SetPrivateConversationDataAsync>d__1`1.MoveNext() System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start(TStateMachine& stateMachine) Varonis.Bot.Application.PasswordResponseFunction.SetPrivateConversationDataAsync(IMessageActivity messageActivity, String key, T value) Varonis.Bot.Application.PasswordResponseFunction.<Run>d__0.MoveNext() in PasswordResponseFunction.cs: line: 48
Additional Info
I Actually opened the Microsoft.Bot.Builder.dll with a decompiler (JetBrains dotPeek), and couldn’t find the Conversation class there. But when I pressed F12 on the property in the code, the VS decompiler did take me to the property.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 19 (7 by maintainers)
I found a workaround for this. This bug is a manifestation of a bug in the function host, which is tied to Autofac 4.2.1. see Azure/azure-functions-host#2979 and Azure/azure-functions-host#1665. So to work around, I downgraded Autofac in my function to 4.2.1, and the problem disappeared.
How is this closed? was a fix checked in?
I was not using AzureFunctions.Autofac, but repro’d the exact same issue. Pretty weird. Played with versions of the Nuget packages and all.
I’m just gonna roll back some changes, and switch over to the Web App version. I was actually working on transitioning a pre-prod bot over to Functions, for the scalability. But this’ll have to do for our purposes. Considering there’s an Azure template for building a Function-based bot, you’d like to think it…worked. But so it goes.
Glad I found this thread, though! I’ve been banging my head for an hour.
Our considerations for choosing a functions bot were a) hopefully it will cost less, since (in Consumption plan) you only pay for actual CPU time. This is an internal organization bot, with a few dozens requests per day. And b) it’s a chance to learn new technology, which is always fun 😃