In process of migrating from .net framework and are struggling with a difference of response serialization.
Everything here seems to indicate that by default a response will go out via the json serializer.
https://learn.microsoft.com/en-us/aspnet/core/web-api/advanced/formatting?view=aspnetcore-5.0 but when returning a simple string value all our endpoints have the content type of "text/plain" so the text isn’t surrounded by quotes.
Given this basic controller:
[ApiController]
[Route("[controller]")]
public class SanityController : ControllerBase
{
public SanityController()
{
}
[HttpGet0]
public string Get()
{
return "Where are the quotes?";
}
}
And our Program.cs:
var builder = WebApplication.CreateBuilder(args);
...
// Tried this as well, not sure what the difference even is between this an AddJsonOptions, seemed to work the same.
//builder.Services.Configure<JsonOptions>(options =>
//{
// options.SerializerOptions.IncludeFields = true;
// options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
// options.SerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
// options.SerializerOptions.PropertyNameCaseInsensitive = true;
//});
...
builder.Services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.IncludeFields = true;
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
});
...
app.Run();
But the Content-Type returned for all of our endpoints that return strings is just "text/plain". We tried changing the Accept header on our client from
application/json, text/plain, */*
to application/json, text/plain;q=0.9, */*;q=0.8
but it would still return text. Only if we only set it to just application/json
would it finally return json. But this doesn’t help when hitting it directly from a browser window where it will again just return it as "text/plain".
We also found could also put [Produces("application/json")]
on the controller method and that would also work.
But considering 99% of all our endpoints should return JSON with barely a handful returning text or xml, is there not a way to change the aggressive default for a string response to be application/json
app wide like it was with asp.net?
2
Answers
You can remove
StringOutputFormatter
(if needed add it to the end withoptions.OutputFormatters.Add(new StringOutputFormatter());
afterRemoveType
call):String value is a valid JSON, however it is confusing to ASP.Net core and it can’t know if you intended it to be an application/json or a text/plain.
What you can do in this case, is to specify that you need a application/json in the request levraging content negotation.
using the Accept to be
application/json
will make asp.net core returnapplication/json
instead of text/plain.And the proper header.
Or else if you want to do it in a global manner, you can remove the
plain/text formatter :
This, of course, will prevent you from never being able to send text/plain back. even if you set the Produces Attribute, or send an Accept header with text/plain.