0

In Blazor Server I'm calling a web service and storing the results in a dynamic object. I want to either convert that dynamic object to a Dictionary object or pass it through to a method so that I can write it to a file. But whatever I try to do with the object, other than to converting it to a String, I get a Runtime error:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Message=The best overloaded method match for 'System.Text.Json.JsonSerializer.Deserialize<System.Collections.Generic.Dictionary<string,object>>(System.Text.Json.JsonDocument, System.Text.Json.JsonSerializerOptions)' has some invalid arguments

My code works fine in a console application, but when I try and run it in Blazor server I get the Runtime Error.

Here is my code:

namespace BlazorWebAssembly.Server.Endpoints
{
    public static class CybsAuthEndpoint
    {
        static SaveAuthData saveAuthData = new SaveAuthData();
        private static string Id = string.Empty;
        public static async void MapCybsCall(this WebApplication app)
        {
            ICallForCybsAuth cybsAuth = new CallForCybsAuth();
            dynamic jsonObject = new ExpandoObject();
            jsonObject = cybsAuth.RunAsyncJson();

            var options = new JsonSerializerOptions { WriteIndented = true, Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
            var jsonString = JsonSerializer.Serialize(jsonObject, options);
            Console.WriteLine(jsonString);

            //**** This is what throws the Runtime Error: 
            var dict = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(jsonObject); 
            //****

            app.MapGet("/cybersource", () =>  Results.Ok(jsonObject));
        }
    }
}
dbc
  • 104,963
  • 20
  • 228
  • 340
  • You have a typo: you want to do **`System.Text.Json.JsonSerializer.Deserialize>(jsonString);`** but you are passing **`jsonObject`** not **`jsonString`**. This is one of the many examples of why `dynamic` is bad: you lose all compile time error checking. – dbc May 19 '23 at 20:24
  • OK that is positive feedback as I am a noob when it comes to dynamic objects. So the best practice is to convert them to a known type, in this case string, then convert that to Dictionary to pass to a method? – Adam Williams May 19 '23 at 20:30
  • My problem is that if I convert the string to a Dictionary I lose the JSON formatting which I'm trying to keep for the file write. – Adam Williams May 19 '23 at 20:36
  • 1) Did `JsonSerializer.Deserialize>(jsonString)` fix the problem? 2) If you want to retain formatting you can deserialize to `JsonElement` or `JsonDocument` which do retain formatting. Just declare them as what they really are, not `dynamic`. 3) What does `cybsAuth.RunAsyncJson()` return anyway? 4) See also [Is the use of dynamic considered a bad practice?](https://stackoverflow.com/q/31859016). – dbc May 19 '23 at 20:40
  • No that didn't solve my problem. I will research the possibility of using JsonDocument. RunAsyncJson() returns an ExpadoObject from a REST webservice. When I started going line by line to see why my console app worked and my Blazor app didn't I found that making the class that returns the ExpandoObject static fixed my problem. I have no idea why though. So anyway my code is working now. Thanks for the suggestions. – Adam Williams May 19 '23 at 22:35

0 Answers0