-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deserialization Failure with WaterfallStepContext.Values #4
Comments
@karamem0 Thanks! Would it be possible to share the code for a repro? This was one of the trickier areas to switch from NewtonSoft to System.Text.Json. |
@karamem0 I have a dialog like this. Same as yours?
|
Hi @tracyboehrer, |
As a workaround, I created the extension method. public static class WaterfallStepContextExtensions
{
public static void SetValue<T>(this WaterfallStepContext target, string key, T? value)
{
target.Values[key] = JsonSerializer.Serialize(value);
}
public static T? GetValue<T>(this WaterfallStepContext target, string key)
{
if (target.Values.TryGetValue(key, out var value))
{
if (value is string jsonStr)
{
return JsonSerializer.Deserialize<T>(jsonStr);
}
else
if (value is JsonElement element)
{
var jsonObj = element.GetString();
if (jsonObj is not null)
{
return JsonSerializer.Deserialize<T>(jsonObj);
}
}
}
return default;
}
} |
@karamem0 My version works with MemoryStorage, which if we're doing the same thing the problem isn't where I thought it would be. Possibly CosmosDbPartitionedStorage? I will check that next. My initial guess was something up the chain... ObjectPath. Because whatever it's doing, the serializer doesn't like it. In all likelihood, this is just a difference between System.Text.Json and NewtonSoft, and we didn't account for it. |
@karamem0 So not storage related which makes sense because that isn't in the stack. Though, I can't reproduce. Cleary it's happening for you. |
I changed your code a little then I could reproduce the issue. using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Agents.BotBuilder;
using Microsoft.Agents.BotBuilder.Dialogs;
using Microsoft.Agents.Protocols.Primitives;
namespace EchoBot.Dialogs
{
public class TestDialog : ComponentDialog
{
public TestDialog(UserState userState)
: base(nameof(TestDialog))
{
// This array defines how the Waterfall will execute.
var waterfallSteps = new WaterfallStep[]
{
StepOne,
StepTwo,
StepThree
};
// Add named dialogs to the DialogSet. These names are saved in the dialog state.
AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new TextPrompt(nameof(TextPrompt)));
AddDialog(new TextPrompt(nameof(TextPrompt)));
// The initial child Dialog to run.
InitialDialogId = nameof(WaterfallDialog);
}
private static async Task<DialogTurnResult> StepOne(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["Value1"] = new Dictionary<string, object?>() { { "Key1", "Value1" } };
return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("One") }, cancellationToken);
}
private static async Task<DialogTurnResult> StepTwo(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
- stepContext.Values["Value2"] = "This is a bot";
+ stepContext.Values["Value2"] = new Dictionary<int, object?>() { { 2, "Value2" } };
return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Two") }, cancellationToken);
}
private static async Task<DialogTurnResult> StepThree(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text($"Three: {stepContext.Result}") }, cancellationToken);
}
}
} |
@karamem0 Thanks! I'll dig into this. |
@karamem0 This is a different from the original exception, right? I can reproduce the |
@karamem0 The issue in the more recent repro is with the DictionaryOfObjectConverter converter. Just doesn't like the Dictionary<int,object>. I'll let you know. System.Text.Json just doesn't handle this the same way. |
@karamem0 I have a resolution for |
Version
What package version of the SDK are you using.
Describe the bug
When inserting objects of different types into WaterfallStepContext.Values, the deserialization process fails.
To Reproduce
BlobsStorage
asIStorage
.WaterfallDialog
, .Add
Dictionary<string, object>
object to theStepContext.Value
.Show a prompt and the user responds. (The
Value1
is saved to Blob storage with '$type' and '$typeAssembly')Add
string
object to theStepContext.Value
.Show a prompt and the user responds. (The
Value2
is saved to Blob storage)The JSON is:
Expected behavior
The values should be deserialized with its type or
JsonElement
.Screenshots
N/A
Hosting Information (please complete the following information):
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: