Skip to content

Settings

Run the complete page example.

Calls to the same service often need the same rules: how to write JSON, format a date, add an access token, or handle a failed reply. RefitSettings keeps those choices in one place so you can apply them across a client.

Set up these rules before creating the client. Start with the serializer your service needs, then change the other settings when a request calls for them.

Set the serializer and formatters

1. Prepare generated metadata. Use the context and serializer from client creation.

2. Choose the settings constructor. The serializer is required in these constructor overloads. A null formatter selects the default formatter.

RefitSettings defaults = new() { ContentSerializer = JsonSettings.ContentSerializer };
RefitSettings serializerOnly = new(JsonSettings.ContentSerializer);
RefitSettings values = new(JsonSettings.ContentSerializer, new DefaultUrlParameterFormatter());
RefitSettings forms = new(JsonSettings.ContentSerializer, null, new DefaultFormUrlEncodedParameterFormatter());
RefitSettings keys = new(JsonSettings.ContentSerializer, null, null, new CamelCaseUrlParameterKeyFormatter());

3. Pass the settings to client creation or registration. Reuse the configured serializer. The parameterless constructor creates a System.Text.Json serializer and default formatters. Assign generated JSON metadata before using that serializer in an AOT app. A null serializer passed to a constructor throws ArgumentNullException.

A production client commonly keeps one RefitSettings instance with its generated JSON context and assigns an asynchronous ExceptionFactory when the service has a typed error envelope. Refit awaits this factory. Keep its asynchronous work asynchronous: do not use .Result or .Wait(), which can block a thread and can deadlock code that has a synchronization context. The factory returns an exception for that envelope or null to suppress the HTTP error.

The reflection builder retains the serializer supplied when it is constructed. Other settings may be read when a request is built. Changing shared settings during calls does not provide a uniform reconfiguration contract. Prepare a different settings instance when clients need different rules.

Align naming rules with generated JSON

CamelCase(), SnakeCase() and KebabCase() return new settings. They align the JSON naming policy and URL key formatter. For AOT, replace their serializer with one whose generated context uses the same convention. These contexts register the demonstration model, ClientNamingInput(int PageSize).

[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(ClientNamingInput))]
internal sealed partial class ClientCamelJsonContext : JsonSerializerContext;
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower)]
[JsonSerializable(typeof(ClientNamingInput))]
internal sealed partial class ClientSnakeJsonContext : JsonSerializerContext;
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.KebabCaseLower)]
[JsonSerializable(typeof(ClientNamingInput))]
internal sealed partial class ClientKebabJsonContext : JsonSerializerContext;

The example checks all three shortcuts and writes the model with each generated context.

RefitSettings camel = RefitSettings.CamelCase();
RefitSettings snake = RefitSettings.SnakeCase();
RefitSettings kebab = RefitSettings.KebabCase();
RefitSettings[] naming = [camel, snake, kebab];
System.Text.Json.Serialization.JsonSerializerContext[] contexts = [ClientCamelJsonContext.Default, ClientSnakeJsonContext.Default, ClientKebabJsonContext.Default];
for (int index = 0; index < naming.Length; index++)
{
    RefitSettings settings = naming[index];
    System.Text.Json.Serialization.JsonSerializerContext context = contexts[index];
    JsonSerializerOptions options = new(context.Options) { TypeInfoResolver = context };
    settings.ContentSerializer = new SystemTextJsonContentSerializer(options);
    Console.WriteLine(settings.UrlParameterKeyFormatter.Format(NamingKey));
    using HttpContent content = settings.ContentSerializer.ToHttpContent(new ClientNamingInput(NamingPageSize));
    Console.WriteLine(await content.ReadAsStringAsync());
}

The key/body names are pageSize, page_size and page-size. Register each request, reply and container type your real API uses. See JSON contexts for combining and reusing registrations. An explicit AliasAs name wins over a naming rule. An explicit serializer property name can also control flattened query keys. See query formatters.

URL resolution

UrlResolution defaults to RefitLegacy. Legacy mode requires a leading slash and prepends the base address path. For example, base https://service.example/api/ and route /people produce /api/people.

Rfc3986 uses standard URI resolution. A leading slash replaces the base path: /people produces https://service.example/people. With a base ending in /api/, people produces /api/people. With a base ending in /api, people replaces the final path segment and produces /people. Keep the trailing slash when the base path represents a folder to append to.

Check buffering and unresolved routes

Buffered asks Refit to load the request body into memory before passing it to the HTTP handler. An explicit [Body(true)] or [Body(false)] overrides the client setting for that argument. The policy example checks both client defaults and both attribute overrides. Its handler observes the content length before reading any bytes:

RefitSettings settings = new(serializer) { Buffered = buffer };
ISettingsPolicyApi api = RestService.ForGenerated<ISettingsPolicyApi>(client, settings);
SampleCheck.Equal(BufferingHandler.ReplyText, await api.InheritedAsync(new(1, "Ada")));
SampleCheck.Equal(buffer, handler.LengthBeforeRead.HasValue);
SampleCheck.Equal(BufferingHandler.ReplyText, await api.UnbufferedAsync(new(1, "Ada")));
SampleCheck.Equal(false, handler.LengthBeforeRead.HasValue);
SampleCheck.Equal(BufferingHandler.ReplyText, await api.BufferedAsync(new(1, "Ada")));
SampleCheck.Equal(true, handler.LengthBeforeRead > 0);

The same project declares /policy/{tenant} without a matching method argument. With AllowUnmatchedRouteParameters false, building that request throws ArgumentException. True retains the placeholder for code that will rewrite it later. It does not supply a tenant value.

RefitSettings settings = new(serializer) { AllowUnmatchedRouteParameters = allow };
ISettingsPolicyApi api = RestService.ForGenerated<ISettingsPolicyApi>(client, settings);

Configure either setting before creating the client. The complete example reuses one local HTTP client across the checks and does not contact a server.

Settings reference

Each row describes one constructor, naming factory, or public property. Nullable constructor arguments use null to select the formatter default; they are not optional C# parameters.

MemberDescriptionParametersReturns or value
RefitSettingsHolds the serializer, URL/form formatters, request-building options, exception factories, and HTTP-version settings used by a Refit client.None.Mutable settings object.
RefitSettings()Creates a complete settings object with Refit's default serializer, formatters, and exception factories.None.New settings with the System.Text.Json serializer, default URL, form, and key formatters, plus default exception factories.
RefitSettings(IHttpContentSerializer contentSerializer)Creates settings that use the supplied content serializer and the other defaults.IHttpContentSerializer contentSerializer: serializer; must not be null.New settings using the supplied serializer and default URL, form, and key formatters.
RefitSettings(IHttpContentSerializer contentSerializer, IUrlParameterFormatter? urlParameterFormatter)Creates settings with a supplied serializer and URL-value formatter.IHttpContentSerializer contentSerializer: required serializer; IUrlParameterFormatter urlParameterFormatter: formatter or null for the default.New settings using the supplied choices and the default form and key formatters.
RefitSettings(IHttpContentSerializer contentSerializer, IUrlParameterFormatter? urlParameterFormatter, IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter)Creates settings with supplied serializer, URL-value, and form-value formatters.IHttpContentSerializer contentSerializer: required serializer; IUrlParameterFormatter urlParameterFormatter: formatter or null; IFormUrlEncodedParameterFormatter formUrlEncodedParameterFormatter: formatter or null.New settings using the supplied choices and the default key formatter.
RefitSettings(IHttpContentSerializer contentSerializer, IUrlParameterFormatter? urlParameterFormatter, IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter, IUrlParameterKeyFormatter? urlParameterKeyFormatter)Creates settings with supplied serializer and all formatter choices.IHttpContentSerializer contentSerializer: required serializer; IUrlParameterFormatter urlParameterFormatter: formatter or null; IFormUrlEncodedParameterFormatter formUrlEncodedParameterFormatter: formatter or null; IUrlParameterKeyFormatter urlParameterKeyFormatter: formatter or null.New settings; a null formatter selects its default.
RefitSettings.CamelCase()Creates settings that serialize JSON and format URL/form keys in camelCase.None.New RefitSettings using camelCase JSON and URL/form keys.
RefitSettings.SnakeCase()Creates settings that serialize JSON and format URL/form keys in snake_case.None.New RefitSettings using snake_case JSON and URL/form keys.
RefitSettings.KebabCase()Creates settings that serialize JSON and format URL/form keys in kebab-case.None.New RefitSettings using kebab-case JSON and URL/form keys.
AuthorizationHeaderValueGetterSupplies a token for a declared [Authorize] header that has no token. Generated preparation uses it even with a supplied HttpClient; a settings-created handler also uses it for an explicit token.Func<HttpRequestMessage, CancellationToken, ValueTask<string>> or null.Token getter; default null. An empty returned token removes the header.
HttpMessageHandlerFactorySupplies the primary handler when Refit creates the HttpClient.Func<HttpMessageHandler> or null.Handler factory; default null. Refit ignores it when you supply an existing HttpClient.
ExceptionFactoryMaps unsuccessful HTTP responses to exceptions.Func<HttpResponseMessage, ValueTask<Exception?>>.Exception factory; default creates Refit API exceptions. A null result suppresses the HTTP error.
DeserializationExceptionFactoryMaps response-body deserialization failures to exceptions.Func<HttpResponseMessage, Exception, ValueTask<Exception?>> or null.Deserialization exception factory; default null. A null result suppresses the error.
ContentSerializerSerializes request bodies and deserializes response bodies.IHttpContentSerializer.Body/reply serializer; default SystemTextJsonContentSerializer.
ReturnTypeAdaptersRegisters custom return wrappers for the opt-in reflection request builder, such as IObservable<T>.Read-only IList<Type> property.Mutable adapter list; default empty. Reflection builds consult it; source-generated builds discover adapters at compile time.
UrlParameterKeyFormatterFormats parameter names used in route, query, and form data.IUrlParameterKeyFormatter.URL/form key formatter; default DefaultUrlParameterKeyFormatter.
HonorContentSerializerPropertyNamesInQueryChooses whether flattened query names follow serializer property names.bool.true makes flattened query keys honor serializer names; default true. AliasAs wins in either mode.
UrlParameterFormatterFormats parameter values inserted into URLs.IUrlParameterFormatter.Path/query value formatter; default DefaultUrlParameterFormatter.
UrlParameterFormatterMapSelects URL value formatters by exact runtime type before the general formatter.Read-only IDictionary<Type, IUrlParameterFormatter> property.Mutable formatter map; default empty. Base classes and interfaces are not searched.
FormUrlEncodedParameterFormatterFormats values written into form-url-encoded request bodies.IFormUrlEncodedParameterFormatter.Form value formatter; default DefaultFormUrlEncodedParameterFormatter.
CollectionFormatSelects how collection values become repeated or joined URL parameters.CollectionFormat.Collection rendering mode; default RefitParameterFormatter.
BufferedChooses whether request content is buffered before the HTTP send.bool.Buffer request content before sending; default false.
CaptureRequestContentCaptures request-body text so an ApiExceptionBase can expose it after a failed request.bool.Retain request-body text in memory; default false. Avoid it for large or streamed uploads.
CaptureMethodArgumentsStores boxed interface-call arguments in the request options for a handler to inspect.bool.Retain an object?[] for the request lifetime; default false.
MaxExceptionContentLengthLimits the response-body characters captured while building an API exception.int? characters.Error-body capture limit; default null (unbounded).
ExceptionRedactorScrubs sensitive data from an ApiExceptionBase before Refit returns it.Action<ApiExceptionBase> or null.Exception scrubbing hook; default null.
AllowUnmatchedRouteParametersAllows route placeholders without matching method parameters.bool.Leaves unmatched {token} text for later rewriting when true; default false.
ValidateHeadersEnables framework validation when Refit applies declared headers.bool.Use framework header parsing; default false. Invalid values throw FormatException when a request is built.
UrlResolutionSelects how relative request paths resolve against HttpClient.BaseAddress.UrlResolutionMode.Base-address resolution mode; default RefitLegacy.
RequestBodySerializationSelects how Refit creates JSON request-body content.RequestBodySerializationMode.JSON body serialization mode; default Default. Buffered and Streamed require ISynchronousContentSerializer.
RequestCompressionSelects the content encoding applied to every request body.RequestCompression.Request-body coding; default None. A [Body] coding overrides this setting.
RequestCompressionLevelSets the compression effort for compressed request bodies.CompressionLevel.Compression effort; default Optimal.
RequestCompressionOptionsProvides per-coding compressor settings that override the compression level for that coding.RequestCompressionOptions or null (.NET 9+).Per-coding compressor settings; default null, which uses the compression level.
HttpRequestMessageOptionsCopies these local values to every generated request's options on modern .NET, or properties on .NET Framework.Dictionary<string, object> or null; init only.Local request values; default null. The dictionary remains mutable after initialization.
TransportExceptionFactoryMaps exceptions thrown by HttpClient.SendAsync to the exception Refit surfaces.Func<HttpRequestMessage, Exception, CancellationToken, Exception>.Default preserves an OperationCanceledException when its token was cancelled; otherwise it wraps the failure in ApiRequestException.
VersionSets the HTTP version requested on generated requests.Version (.NET 6+).Requested HTTP version; default HTTP/1.1.
VersionPolicySets the policy used when negotiating the requested HTTP version.HttpVersionPolicy (.NET 6+).Version negotiation policy; default RequestVersionOrLower.

The enum values used by these properties are:

EnumValueMeaning
CollectionFormatRefitParameterFormatter (0)Use the configured value formatter.
CollectionFormatCsv (1), Ssv (2), Tsv (3), Pipes (4)Comma, space, tab, or pipe separated values.
CollectionFormatMulti (5)Repeat the parameter for each value.
CollectionFormatIndexed (6)Expand object elements with indexed keys.
RequestBodySerializationModeDefault (0)Normal asynchronous serialization.
RequestBodySerializationModeBuffered (1)Synchronous serialization into buffered content.
RequestBodySerializationModeStreamed (2)Synchronous serialization to the request stream.
RequestCompressionDefault (0), None (1), GZip (2), Brotli (3), Zstandard (4)Use settings, no coding, gzip, Brotli, or Zstandard. Brotli requires .NET 8; Zstandard requires .NET 11.
CompressionLevelOptimal (0), Fastest (1), NoCompression (2), SmallestSize (3)Compression effort choices used by RequestCompressionLevel.
UrlResolutionModeRefitLegacy (0), Rfc3986 (1)Legacy base-path prepending or RFC 3986 URI resolution.
System.Net.Http.HttpVersionPolicyRequestVersionOrLower (0), RequestVersionOrHigher (1), RequestVersionExact (2)HTTP version negotiation choices.

Source: RefitSettings.cs at Refit SHA 6f0507fa061f1844a8da6ea92e839b622dfc74ef.

ReturnTypeAdapters and UrlParameterFormatterMap expose mutable collections through read-only properties. Registering a formatter map entry makes generated calls use the formatter route instead of the built-in formatting branch. HttpRequestMessageOptions is init-only, but its dictionary remains mutable. Configure all three before calls begin.

Request bodies explains buffering, compression and body ownership. Headers explains validation and token declarations. .NET Framework settings omit Version, VersionPolicy and compression options. .NET 8 includes HTTP version settings but omits compression options.