Overview
Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json binds Codebelt.Extensions.Carter to a concrete Carter negotiator that serializes responses with Newtonsoft.Json. Use it when Carter endpoints must participate in response negotiation but your application depends on Newtonsoft.Json features such as its converter ecosystem or contract resolver model.
The package keeps the public surface tight. It contributes one negotiator type that reuses the base negotiation flow from the core package while selecting a NewtonsoftJsonFormatter and a UTF-8 default response encoding.
Key APIs
NewtonsoftJsonNegotiator is the package's central type. It derives from ConfigurableResponseNegotiator<NewtonsoftJsonFormatterOptions>, which means the inherited CanHandle, GetEncoding, and Handle<T> flow becomes a concrete negotiator for JSON responses backed by Newtonsoft.Json.
NewtonsoftJsonNegotiator(IOptions<NewtonsoftJsonFormatterOptions>) connects the negotiator to dependency-injected formatter settings, so serializer behavior and supported media types come from the same options used elsewhere in the application.
NewtonsoftJsonNegotiator.GetFormatter builds the NewtonsoftJsonFormatter instance that writes the negotiated response body from the current formatter options.
Basic usage
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json;
using Codebelt.Extensions.Newtonsoft.Json.Formatters;
using Codebelt.Extensions.Xunit;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using Xunit;
namespace MyProject.Tests;
public class NewtonsoftJsonNegotiationTest : Test
{
public NewtonsoftJsonNegotiationTest(ITestOutputHelper output) : base(output) { }
[Fact]
public async Task ShouldSerializeNegotiatedJsonResponse()
{
var context = new DefaultHttpContext();
context.Response.Body = new MemoryStream();
var negotiator = new NewtonsoftJsonNegotiator(Options.Create(new NewtonsoftJsonFormatterOptions()));
Assert.True(negotiator.CanHandle(MediaTypeHeaderValue.Parse("application/json")));
await negotiator.Handle(context.Request, context.Response, new WorkOrder { Id = 7, State = "archived" }, CancellationToken.None);
context.Response.Body.Position = 0;
var body = await new StreamReader(context.Response.Body).ReadToEndAsync();
TestOutput.WriteLine(body);
Assert.StartsWith("application/json", context.Response.ContentType);
Assert.Contains("archived", body);
}
private sealed class WorkOrder { public int Id { get; init; } public string State { get; init; } }
}
Use this pattern when your Carter endpoints must negotiate JSON responses through Newtonsoft.Json rather than the built-in serializer. It matters because the negotiator keeps those serializer-specific rules in one registration point instead of duplicating JSON response handling across endpoints.
Installation
dotnet add package Codebelt.Extensions.Carter.AspNetCore.Newtonsoft.Json
Usage guidance
Choose this package when existing Newtonsoft.Json converters, naming policies, or contract settings are part of the API contract your Carter application must preserve. If you prefer the lighter System.Text.Json stack and do not need Newtonsoft.Json-specific behavior, Codebelt.Extensions.Carter.AspNetCore.Text.Json is the simpler sibling package.