Skip to content

System.Net.Http.Json ReadFromJsonAsync silently can't deserialize generic class in Blazor #21030

@Regenhardt

Description

@Regenhardt

Describe the bug

Trying to deserialize a generic class or struct using the new ReadFromJsonAsync from System.Net.Http.Json fails silently.

I tested it using either a struct or a class. Both work on their own, but not when they carry a generic payload. Making both Result and payload a class deserializes to an empty Result-object with a null payload.

To Reproduce

I used a struct for both used Types here as that is my specific use case, but the same happens when using classes instead.

  1. Create a new hosted Blazor WebAssembly project with the default template as BlazorApp1.Client, .Shared and .Server respectively.

  2. Add the following class to the .Shared Project:

	public struct Result<T>
	{
		private Result(bool success, T data, string message = null)
		{
			Success = success;
			Data = data;
			Message = message;
		}

		public bool Success { get; private set; }

		public T Data { get; private set; }

		public string Message { get; private set; }

		public static Result<T> Positive(T data, string message = null)
		{
			return new Result<T>(true, data, message);
		}

		public override string ToString()
		{
			return $"Result: {Success}, Data: {Data}, Message: {Message}";
		}
	}
  1. Add the following code to the WeatherForecastController to simply send a random WeatherForecast to the caller:
        [HttpPost]
        public Result<WeatherForecast> Post(string _)
        {
            var rng = new Random();
            return Result<WeatherForecast>.Positive(Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            }).First());
        }
  1. Add the following to the .Client's FetchData.razor html section:
<button @onclick="DataViaPost">Get data via post</button>

    <h1>Data from POST</h1>
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
        </tbody>
    </table>

And this to the code section:

    private WeatherForecast forecast;
    async Task DataViaPost()
    {
        var response = await Http.PostAsJsonAsync<string>("WeatherForecast", "dummy");
        Console.WriteLine($"Response: {response}");

        string content = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Content as string: \n{content}");

        var result = await response.Content.ReadFromJsonAsync<Result<WeatherForecast>>();
        Console.WriteLine(result);
        if (result.Success) forecast = result.Data;
    }
  1. Start the .Server project
  2. Open the console to observe the browser output
  3. Go to the "Fetch data" page and click the button

The output in the console should look something like this:

image

The readout as string shows the correctly received data.
The deserialized object has no data.

Further technical details

dotnet core sdk: 3.1.201
Windows 10.0.18363 (Update 1909)
Visual Studio 2019 16.5.4

App is netstandard21/netcoreapp31
Included in default template are:
Microsoft.AspNetCore.Components.WebAssembly/.Build/.DevServer 3.2.0-preview4.20210.8
System.Net.Http.Json 3.2.0-preview5.20210.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    ExternalThis is an issue in a component not contained in this repository. It is open for tracking purposes.area-blazorIncludes: Blazor, Razor Components

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions