Using new Json serializer with HttpContext.Response in ASP.NET Core 3.1
Asked Answered
M

1

9

When we want to serialize an object to a JSON string in ASP.NET Core's pipeline, we need to work with HttpContext.Response.Body.WriteAsync, unless I'm missing something, as there's no Result property which we can easily use to assign a JsonResult object to.

Unless there's a better alternative, how exactly is serialization achieved by using the above method?

Note: The options for the JSON serializer should be the same as the (default) ones being used in ASP.NET Core 3.1.

If desired (not in our case), they can be modified via the IServiceCollection.AddJsonOptions middleware.

Example:

app.Use( next =>
{
    return async context =>
    {
        if (<someFunkyConditionalExample>)
        {
            // serialize a JSON object as the response's content, returned to the end-user.
            // this should use ASP.NET Core 3.1's defaults for JSON Serialization.
        }
        else
        {
            await next(context);
        }
    };
});
Maladjustment answered 16/3, 2020 at 14:3 Comment(15)
I believe native JSON support was added via System.Text.Json. Have you tried working with that? devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apisPamalapamela
Can you send the object as such so that the .net runtime itself serializes it as json and sends the response as json to the caller. something like the one below. // GET api/authors/RickAndMSFT [HttpGet("{alias}")] public Author Get(string alias) { return _authors.GetByAlias(alias); }Tub
I'm confused by your question. What exactly are you trying to do? Are you just trying to serialise? So something like var json = System.Text.Json.JsonSerializer.Serialize(new {x = 5})?Simmon
@JWeezy I'm not sure how exactly I can work with the library, when WriteAsync expects a byte[] along with int offset and int count arguments.Maladjustment
There is an extension method that works directly with strings learn.microsoft.com/en-us/dotnet/api/…Simmon
@Simmon I'm trying to pass in the object by using the HttpContext we receive in ASP.NET Core 3.1's pipeline. It has no Result property, so the only thing I'm able to do, is use HttpContext.Response.Body.WriteAsync method, which frankly confuses me.Maladjustment
What do you mean by "pass in the object"? Are you trying to write JSON to the consumer of your API?Simmon
@Maladjustment Based on the comments, you may need to post your code so we can get a better idea on how to help.Pamalapamela
@Simmon yes, that's the idea. JWeazy I'll do that in a minute.Maladjustment
Aren't you missing the Ok() method?Hogback
So use those extension methods to write strings, or is there something else?Simmon
@Simmon how exactly would I fetch ASP.NET Core 3.1's configuration of the JSON serializer it uses? Example attached.Maladjustment
Just return the object from your controller method. ASP.NET will serialize it to JSON by default.Bookish
@IanKemp That's the thing. I want to do it from the pipeline.Maladjustment
@Maladjustment Why?Bookish
S
7

First of all, you can use these extension methods to write strings directly to your response, for example:

await context.Response.WriteAsync("some text");

Make sure you have imported the correct namespace to give you access to these extensions:

using Microsoft.AspNetCore.Http;

Secondly, if you want to get the JSON serialiser settings that are being used by the framework, you can extract them from the DI container:

var jsonOptions = context.RequestServices.GetService<IOptions<JsonOptions>>();

So this would make your full pipeline code look a little like this:

app.Use(next =>
{
    return async context =>
    {
        if (<someFunkyConditionalExample>)
        {
            // Get the options
            var jsonOptions = context.RequestServices.GetService<IOptions<JsonOptions>>();

            // Serialise using the settings provided
            var json = JsonSerializer.Serialize(
                new {Foo = "bar"}, // Switch this with your object
                jsonOptions?.Value.JsonSerializerOptions);

            // Write to the response
            await context.Response.WriteAsync(json);
        }
        else
        {
            await next(context);
        }
    };
});
Simmon answered 16/3, 2020 at 15:16 Comment(4)
Wow! RequestServices is right there in the HttpContext. This is good to know.Kasiekask
What namespace is JsonOptions in?Miltonmilty
I create a library with target framework .NET Core 3.1. I then added the Microsoft.AspNetCore.Mvc package, but could not find JsonOptionsMiltonmilty
I added the Microsoft.AspNetCore.Mvc.NewtonsoftJson package that solved the problem. But I don't want the dependency on Json.NET. I prefer System.Text.JsonMiltonmilty

© 2022 - 2024 — McMap. All rights reserved.