| name | serialize-json |
| description | ABP IJsonSerializer and its default System.Text.Json provider. USE FOR: Serialize/Deserialize overloads; camelCase and indented flags; AbpSystemTextJsonSerializerOptions.JsonSerializerOptions; AbpJsonOptions date formats; ABP converters and JSON contract modifiers. DO NOT USE FOR: ASP.NET Core MVC response JSON (out of scope); distributed cache entry serialization (distributed-caching-and-locking); encrypting serialized values (encrypt-strings). |
| license | MIT |
Serialize JSON in ABP
Use IJsonSerializer in reusable application and infrastructure code. Volo.Abp.Json depends on Volo.Abp.Json.SystemTextJson, so System.Text.Json is the default provider while callers remain provider-independent.
When to Use
- Serialize an object to a JSON string outside the ASP.NET Core formatter pipeline.
- Deserialize to a generic type or a runtime
Type.
- Share ABP's converters, date handling, and extra-property contract behavior.
- Configure the default System.Text.Json provider for consumers of
IJsonSerializer.
When Not to Use
- Configure controller response/request JSON — configure ASP.NET Core
JsonOptions separately; that is ASP.NET Core HTTP formatter configuration and is out of scope here.
- Design distributed cache serialization and expiration policy — use distributed-caching-and-locking.
- Protect JSON as a secret — use encrypt-strings only when ABP-compatible reversible encryption is the requirement.
How it works
Use the abstraction
IJsonSerializer is synchronous and exposes three operations:
string Serialize(object obj, bool camelCase = true, bool indented = false);
T Deserialize<T>(string jsonString, bool camelCase = true);
object Deserialize(Type type, string jsonString, bool camelCase = true);
public class PayloadStore : ITransientDependency
{
private readonly IJsonSerializer _jsonSerializer;
public PayloadStore(IJsonSerializer jsonSerializer)
{
_jsonSerializer = jsonSerializer;
}
public string Serialize(OrderPayload payload)
{
return _jsonSerializer.Serialize(payload);
}
public OrderPayload Deserialize(string json)
{
return _jsonSerializer.Deserialize<OrderPayload>(json);
}
}
camelCase defaults to true; indented defaults to false. Pass camelCase: false when property names must retain their CLR names.
Configure the default System.Text.Json provider
AbpSystemTextJsonSerializerOptions.JsonSerializerOptions starts with JsonSerializerDefaults.Web, skips comments, and allows trailing commas. The ABP module supplies an unsafe-relaxed encoder only when no encoder was explicitly set, then adds ABP converters and an AbpDefaultJsonTypeInfoResolver.
using System.Text.Json.Serialization;
using Volo.Abp.Json.SystemTextJson;
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
options.JsonSerializerOptions.DefaultIgnoreCondition =
JsonIgnoreCondition.WhenWritingNull;
});
The serializer clones these global options for each camelCase/indented combination, overriding PropertyNamingPolicy and WriteIndented for the current call.
Configure ABP DateTime formats
AbpJsonOptions has two properties:
InputDateTimeFormats: an empty List<string> by default; add exact accepted input formats.
OutputDateTimeFormat: null by default; null or empty uses the provider's default output format.
using Volo.Abp.Json;
Configure<AbpJsonOptions>(options =>
{
options.InputDateTimeFormats.Add("yyyy-MM-dd HH:mm:ss");
options.OutputDateTimeFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'";
});
The ABP DateTime converters use these values with CultureInfo.CurrentUICulture. Note the two layers behave differently. The default System.Text.Json provider registers its date converters with SkipDateTimeNormalization(), so the general path does not call Clock.Normalize — a value with a specified Kind passes through unchanged. The converter still handles specific cases: a DateTime with Unspecified kind, under a clock that supports multiple timezones and a current tenant timezone, is converted from that timezone to UTC. A literal Z format does not itself convert a value to UTC; choose the format together with the application's clock policy.
Keep ASP.NET Core JSON configuration separate
Configuring AbpSystemTextJsonSerializerOptions or AbpJsonOptions does not configure ASP.NET Core MVC's input/output formatter. Configure Microsoft ASP.NET Core JsonOptions separately when HTTP contracts must change.
Validation
- Round-trip representative payloads, including nulls, enums, GUIDs,
DateTime, and extra properties.
- Assert both camel-case and CLR-name modes when consumers depend on property casing.
- Test malformed JSON, comments, and trailing commas according to the configured policy.
- Verify the runtime
Type overload returns the expected concrete type.
- Test
IJsonSerializer and ASP.NET Core endpoint JSON separately; they use separate option objects.
Common Pitfalls
- Calling
System.Text.Json.JsonSerializer directly in provider-independent code — it bypasses ABP's abstraction and converters.
- Expecting ABP options to change MVC JSON — ASP.NET Core formatter options are separate.
- Assuming
indented is a global setting — it is a per-call argument on IJsonSerializer.Serialize.
- Adding a date output suffix that misrepresents the value's timezone — formatting does not replace correct clock normalization.
- Mutating serializer options after first use — configure options during module service configuration, before serializers cache cloned option sets.