diff --git a/libraries/Microsoft.Bot.Builder/BotState.cs b/libraries/Microsoft.Bot.Builder/BotState.cs index a55695889e..3e171b477e 100644 --- a/libraries/Microsoft.Bot.Builder/BotState.cs +++ b/libraries/Microsoft.Bot.Builder/BotState.cs @@ -119,6 +119,29 @@ public IStatePropertyAccessor CreateProperty(string name) return Task.CompletedTask; } + /// + /// Delete any state currently stored in this state scope. + /// + /// The context object for this turn. + /// cancellation token. + /// A representing the asynchronous operation. + public async Task DeleteAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) + { + if (turnContext == null) + { + throw new ArgumentNullException(nameof(turnContext)); + } + + var cachedState = turnContext.TurnState.Get(_contextServiceKey); + if (cachedState != null) + { + turnContext.TurnState.Remove(_contextServiceKey); + } + + var storageKey = GetStorageKey(turnContext); + await _storage.DeleteAsync(new[] { storageKey }, cancellationToken).ConfigureAwait(false); + } + /// /// When overridden in a derived class, gets the key to use when reading and writing state to and from storage. /// diff --git a/tests/Microsoft.Bot.Builder.Tests/BotStateTests.cs b/tests/Microsoft.Bot.Builder.Tests/BotStateTests.cs index 68f9ad0e8b..e762bb5226 100644 --- a/tests/Microsoft.Bot.Builder.Tests/BotStateTests.cs +++ b/tests/Microsoft.Bot.Builder.Tests/BotStateTests.cs @@ -725,6 +725,42 @@ public async Task ClearAndSave() Assert.AreEqual("default-value", value2); } + [TestMethod] + public async Task BotStateDelete() + { + var turnContext = TestUtilities.CreateEmptyContext(); + turnContext.Activity.Conversation = new ConversationAccount { Id = "1234" }; + + var storage = new MemoryStorage(new Dictionary()); + + // Turn 0 + var botState1 = new ConversationState(storage); + (await botState1 + .CreateProperty("test-name") + .GetAsync(turnContext, () => new TestPocoState())).Value = "test-value"; + await botState1.SaveChangesAsync(turnContext); + + // Turn 1 + var botState2 = new ConversationState(storage); + var value1 = (await botState2 + .CreateProperty("test-name") + .GetAsync(turnContext, () => new TestPocoState { Value = "default-value" })).Value; + + Assert.AreEqual("test-value", value1); + + // Turn 2 + var botState3 = new ConversationState(storage); + await botState3.DeleteAsync(turnContext); + + // Turn 3 + var botState4 = new ConversationState(storage); + var value2 = (await botState4 + .CreateProperty("test-name") + .GetAsync(turnContext, () => new TestPocoState { Value = "default-value" })).Value; + + Assert.AreEqual("default-value", value2); + } + public class TestBotState : BotState { public TestBotState(IStorage storage)