diff --git a/IntermediatorBotSample.sln b/IntermediatorBotSample.sln index 86cfc1e..6e8021d 100644 --- a/IntermediatorBotSample.sln +++ b/IntermediatorBotSample.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 15.0.27428.2037 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntermediatorBotSample", "IntermediatorBotSample\IntermediatorBotSample.csproj", "{C5442A0C-E1AB-4237-B069-097A470AF818}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotMessageRouting", "bot-message-routing\BotMessageRouting\BotMessageRouting.csproj", "{E2A695B5-29F9-450A-8809-CB57B40619F6}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -17,10 +15,6 @@ Global {C5442A0C-E1AB-4237-B069-097A470AF818}.Debug|Any CPU.Build.0 = Debug|Any CPU {C5442A0C-E1AB-4237-B069-097A470AF818}.Release|Any CPU.ActiveCfg = Release|Any CPU {C5442A0C-E1AB-4237-B069-097A470AF818}.Release|Any CPU.Build.0 = Release|Any CPU - {E2A695B5-29F9-450A-8809-CB57B40619F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E2A695B5-29F9-450A-8809-CB57B40619F6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E2A695B5-29F9-450A-8809-CB57B40619F6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E2A695B5-29F9-450A-8809-CB57B40619F6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/IntermediatorBotSample/.config/dotnet-tools.json b/IntermediatorBotSample/.config/dotnet-tools.json new file mode 100644 index 0000000..0595942 --- /dev/null +++ b/IntermediatorBotSample/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-ef": { + "version": "5.0.11", + "commands": [ + "dotnet-ef" + ] + } + } +} \ No newline at end of file diff --git a/IntermediatorBotSample/Bot/IntermediatorBot.cs b/IntermediatorBotSample/Bot/IntermediatorBot.cs index 2ce893d..189b599 100644 --- a/IntermediatorBotSample/Bot/IntermediatorBot.cs +++ b/IntermediatorBotSample/Bot/IntermediatorBot.cs @@ -3,6 +3,7 @@ using Microsoft.Bot.Builder; using Microsoft.Bot.Schema; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace IntermediatorBotSample.Bot @@ -11,7 +12,7 @@ public class IntermediatorBot : IBot { private const string SampleUrl = "https://github.com/tompaana/intermediator-bot-sample"; - public async Task OnTurn(ITurnContext context) + public async Task OnTurnAsync(ITurnContext context, CancellationToken ct) { Command showOptionsCommand = new Command(Commands.ShowOptions); @@ -33,7 +34,7 @@ public async Task OnTurn(ITurnContext context) Activity replyActivity = context.Activity.CreateReply(); replyActivity.Attachments = new List() { heroCard.ToAttachment() }; - await context.SendActivity(replyActivity); + await context.SendActivityAsync(replyActivity); } } } diff --git a/IntermediatorBotSample/CommandHandling/CommandHandler.cs b/IntermediatorBotSample/CommandHandling/CommandHandler.cs index b67f433..51cd1d5 100644 --- a/IntermediatorBotSample/CommandHandling/CommandHandler.cs +++ b/IntermediatorBotSample/CommandHandling/CommandHandler.cs @@ -266,7 +266,7 @@ await _connectionRequestHandler.AcceptOrRejectRequestAsync( if (replyActivity != null) { - await context.SendActivity(replyActivity); + await context.SendActivityAsync(replyActivity); } return wasHandled; diff --git a/IntermediatorBotSample/ConversationHistory/MessageLogs.cs b/IntermediatorBotSample/ConversationHistory/MessageLogs.cs index 741ee6e..c881b6d 100644 --- a/IntermediatorBotSample/ConversationHistory/MessageLogs.cs +++ b/IntermediatorBotSample/ConversationHistory/MessageLogs.cs @@ -32,7 +32,7 @@ public MessageLogs(string connectionString) { System.Diagnostics.Debug.WriteLine("Using Azure Table Storage for storing message logs"); _messageLogsTable = AzureStorageHelper.GetTable(connectionString, MessageLogsTableName); - MakeSureConversationHistoryTableExistsAsync().RunSynchronously(); + MakeSureConversationHistoryTableExistsAsync().Wait(); } } diff --git a/IntermediatorBotSample/IntermediatorBotSample.csproj b/IntermediatorBotSample/IntermediatorBotSample.csproj index 734adbf..6ba7b43 100644 --- a/IntermediatorBotSample/IntermediatorBotSample.csproj +++ b/IntermediatorBotSample/IntermediatorBotSample.csproj @@ -1,27 +1,27 @@ - + - netcoreapp2.0 + netcoreapp3.1 - - - - - + - - - - - - + + + + + + - - - + + + + + + + True diff --git a/IntermediatorBotSample/Middleware/CatchExceptionMiddleware.cs b/IntermediatorBotSample/Middleware/CatchExceptionMiddleware.cs new file mode 100644 index 0000000..99b57ff --- /dev/null +++ b/IntermediatorBotSample/Middleware/CatchExceptionMiddleware.cs @@ -0,0 +1,44 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Bot.Builder.Core.Extensions +{ + /// + /// This piece of middleware can be added to allow you to handle exceptions when they are thrown + /// within your bot's code or middleware further down the pipeline. Using this handler you might + /// send an appropriate message to the user to let them know that something has gone wrong. + /// You can specify the type of exception the middleware should catch and this middleware can be added + /// multiple times to allow you to handle different exception types in different ways. + /// + /// + /// The type of the exception that you want to catch. This can be 'Exception' to + /// catch all or a specific type of exception + /// + public class CatchExceptionMiddleware : IMiddleware where T : Exception + { + private readonly Func _handler; + + public CatchExceptionMiddleware(Func callOnException) + { + _handler = callOnException; + } + + public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken)) + { + try + { + // Continue to route the activity through the pipeline + // any errors further down the pipeline will be caught by + // this try / catch + await next(cancellationToken).ConfigureAwait(false); + } + catch (T ex) + { + // If an error is thrown and the exception is of type T then invoke the handler + await _handler.Invoke(context, ex).ConfigureAwait(false); + } + } + + } +} diff --git a/IntermediatorBotSample/Middleware/HandoffMiddleware.cs b/IntermediatorBotSample/Middleware/HandoffMiddleware.cs index 645116f..4d19d8c 100644 --- a/IntermediatorBotSample/Middleware/HandoffMiddleware.cs +++ b/IntermediatorBotSample/Middleware/HandoffMiddleware.cs @@ -6,6 +6,7 @@ using Microsoft.Bot.Schema; using Microsoft.Extensions.Configuration; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Underscore.Bot.MessageRouting; using Underscore.Bot.MessageRouting.DataStore; @@ -89,7 +90,7 @@ public HandoffMiddleware(IConfiguration configuration) MessageLogs = new MessageLogs(connectionString); } - public async Task OnTurn(ITurnContext context, MiddlewareSet.NextDelegate next) + public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken ct) { Activity activity = context.Activity; @@ -134,7 +135,7 @@ public async Task OnTurn(ITurnContext context, MiddlewareSet.NextDelegate next) else { // No action taken - this middleware did not consume the activity so let it propagate - await next().ConfigureAwait(false); + await next(ct).ConfigureAwait(false); } } } @@ -148,6 +149,11 @@ public async Task OnTurn(ITurnContext context, MiddlewareSet.NextDelegate next) // Handle the result, if necessary await MessageRouterResultHandler.HandleResultAsync(messageRouterResult); } + else + { + // No action taken - this middleware did not consume the activity so let it propagate + await next(ct).ConfigureAwait(false); + } } /// diff --git a/IntermediatorBotSample/Properties/launchSettings.json b/IntermediatorBotSample/Properties/launchSettings.json index 104aad2..a63edbf 100644 --- a/IntermediatorBotSample/Properties/launchSettings.json +++ b/IntermediatorBotSample/Properties/launchSettings.json @@ -22,6 +22,16 @@ "ASPNETCORE_ENVIRONMENT": "Development" }, "applicationUrl": "http://localhost:29211/" + }, + "WSL": { + "commandName": "WSL2", + "launchBrowser": true, + "launchUrl": "http://localhost:29211/", + "environmentVariables": { + "ASPNETCORE_URLS": "http://localhost:29211/", + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "distributionName": "" } } -} +} \ No newline at end of file diff --git a/IntermediatorBotSample/Startup.cs b/IntermediatorBotSample/Startup.cs index 0179b49..73a0f19 100644 --- a/IntermediatorBotSample/Startup.cs +++ b/IntermediatorBotSample/Startup.cs @@ -2,13 +2,17 @@ using IntermediatorBotSample.Middleware; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.Bot.Builder.BotFramework; +using Microsoft.Bot.Builder; using Microsoft.Bot.Builder.Core.Extensions; +using Microsoft.Bot.Builder.BotFramework; +using Microsoft.Bot.Builder.Integration; using Microsoft.Bot.Builder.Integration.AspNet.Core; using Microsoft.Bot.Builder.TraceExtensions; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Server.Kestrel.Core; namespace IntermediatorBotSample { @@ -36,9 +40,18 @@ public Startup(IHostingEnvironment env) /// public void ConfigureServices(IServiceCollection services) { - services.AddMvc().AddControllersAsServices(); + services.AddSingleton(_ => Configuration); - + // If using Kestrel: + services.Configure(options => + { + options.AllowSynchronousIO = true; + }); + // If using IIS: + services.Configure(options => + { + options.AllowSynchronousIO = true; + }); services.AddBot(options => { options.CredentialProvider = new ConfigurationCredentialProvider(Configuration); @@ -50,8 +63,8 @@ public void ConfigureServices(IServiceCollection services) // an "Ooops" message is sent. options.Middleware.Add(new CatchExceptionMiddleware(async (context, exception) => { - await context.TraceActivity("Bot Exception", exception); - await context.SendActivity($"Sorry, it looks like something went wrong: {exception.Message}"); + await context.TraceActivityAsync("Bot Exception", exception); + await context.SendActivityAsync($"Sorry, it looks like something went wrong: {exception.Message}"); })); // The Memory Storage used here is for local bot debugging only. When the bot @@ -73,9 +86,12 @@ public void ConfigureServices(IServiceCollection services) // Handoff middleware options.Middleware.Add(new HandoffMiddleware(Configuration)); + + }); - services.AddMvc(); // Required Razor pages + //services.AddMvc(); // Required Razor pages + services.AddRazorPages(); } /// @@ -93,14 +109,9 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env) app.UseDefaultFiles() .UseStaticFiles() - .UseMvc() // Required Razor pages - .UseBotFramework(bot => - { - // This is how you can define a custom endpoint in case you're unhappy with - // the default "/api/messages": - bot.BasePath = Configuration["BotBasePath"]; - bot.MessagesPath = Configuration["BotMessagesPath"]; - }); + .UseRouting() + .UseBotFramework(); + } } } diff --git a/LICENSE b/LICENSE index 9ae1b05..ddd02a1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016-2018 Microsoft +Copyright (c) 2016-2019 Microsoft Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal