dotnet / dotnet/aspnetcore

Introduce generic `JsonResult<T>`

Open
#55,535 4 comments 0 reactions 0 assignees View on GitHub
api-suggestion area-minimal
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

## Background and Motivation

Currently in `System.Text.Json` we have `JsonSerializer.Serialize(...)` that serializes an object "as T". Which means, if we cast an object to some base class, or to an interface - the serializer will use _that_ exact casted type's properties etc..

HOWEVER the AspNetCore `JsonResult` works differently. When it serializes an object, it always takes the object's hard type. See the source here: https://source.dot.net/#Microsoft.AspNetCore.Mvc.Core/Infrastructure/SystemTextJsonResultExecutor.cs,61 which means that even if we cast the object to something - nah, it does not care, it just uses the actual type.

As a workaround, people either use `JsonSerializer.Serialize` to serialize to intermediate string and then return content (not optimal since it buffers everything into a huge string before sending to the client). Or - people write their own `JsonResult` that handles this (tat's what I did)

## Proposed API

Disclaimer: this is just the code I use as a workaround, it's very simple, and misses stuff, but just to give the idea...

```c#
///
/// Serializes to output stream
/// Almost same as .NET built-in json result but allows specifying a type
///
public class JsonResult : IActionResult
{
private readonly T _value;
private readonly JsonSerializerOptions _options;

public JsonResult(T value, JsonSerializerOptions options)
{
_value = value;
_options = options;
}

public async Task ExecuteResultAsync(ActionContext context)
{
var response = context.HttpContext.Response;
response.ContentType = "application/json";

await JsonSerializer.SerializeAsync(response.Body, _value, _options); //serialize to response stream
await response.Body.FlushAsync();
}
}
```

## Usage Examples

```csharp
public IActionResult Get()
{
return new JsonResult(someData, _someSerializerOptionsField);
}
```

## Alternative Designs

Another option would e to somehow pass the `type` to existing `JsonResult`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.