Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V12: Named json options #13537

Merged
merged 6 commits into from
Dec 12, 2022
Merged

Conversation

Zeegaan
Copy link
Member

@Zeegaan Zeegaan commented Dec 7, 2022

Notes

With the switch to Swashbuckle, we had some trouble serializing plain object types, when receiving one of these types, we would convert it into a JsonElement, which is hard to work with.
This PR remedies that, instead of converting object types to JsonElement, we instead convert the objects to JsonObject.

This gave us some additional challenges, because we can't "just" add our Converters and be done with it. As that would also force anyone using Umbraco to serialize our way (or other projects, like the incoming content delivery API)
We have resolved this by adding our own AddJsonOptions extension, that now also takes a settings name.

We can then register our options like so:

  .AddJsonOptions("BackOffice", options =>
  {
      // all back-office specific JSON options go here
      options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
      options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
      options.JsonSerializerOptions.Converters.Add(new JsonObjectConverter());
  });

And decorate our controller with:

[JsonOptionsName("BackOffice")]
public class ManagementApiControllerBase : Controller
{

}
  • Added JsonObjectConverter class to handle the actual converting of object types.
  • Added MvcBuilderExtensions which contains our extension method of AddJsonOptions()
  • Added ConfigureMvcJsonOptions which handles inserting our custom input/output formatters

How to test

(Try a few different endpoints, they should work as expected)

  • Modify the TelemetryViewModel class like so:
public class TelemetryViewModel
{
    [JsonConverter(typeof(JsonStringEnumConverter))]
    public TelemetryLevel TelemetryLevel { get; set; }

    public object MyObject { get; set; } = new object();
}
  • Call the Get endpoint https://localhost:44331/umbraco/management/api/v1/telemetry/level
  • This should not recurse forever and cause StackOverflow, but instead return the telemetrylevel and an empty object
  • Set a breakpoint in the SetTelemetryController.SetConsentLevel method
  • Try posting to the same endpoint with the property as a string, int, etc. and assert it gets deserialized properly
{
    "telemetryLevel": "Basic",
    "myObject": "test"
}
{
    "telemetryLevel": "Basic",
    "myObject": 123
}

Copy link
Contributor

@nikolajlauridsen nikolajlauridsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a couple of minor things, otherwise, it looks good 👍

Tests out good as well 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants