Json.Masker.SystemTextJson
1.1.14
dotnet add package Json.Masker.SystemTextJson --version 1.1.14
NuGet\Install-Package Json.Masker.SystemTextJson -Version 1.1.14
<PackageReference Include="Json.Masker.SystemTextJson" Version="1.1.14" />
<PackageVersion Include="Json.Masker.SystemTextJson" Version="1.1.14" />
<PackageReference Include="Json.Masker.SystemTextJson" />
paket add Json.Masker.SystemTextJson --version 1.1.14
#r "nuget: Json.Masker.SystemTextJson, 1.1.14"
#:package Json.Masker.SystemTextJson@1.1.14
#addin nuget:?package=Json.Masker.SystemTextJson&version=1.1.14
#tool nuget:?package=Json.Masker.SystemTextJson&version=1.1.14
Json.Masker
Json.Masker is a lightweight library for masking sensitive values during JSON serialization.
Mark properties with [Sensitive], enable the masking context, and the rest happens automatically—no custom DTOs or fragile string hacks.
Supports both Newtonsoft.Json and System.Text.Json.
Packages
| Package | Description |
|---|---|
| Json.Masker.Abstract | Shared abstractions: [Sensitive] attribute, masking strategies, context accessors, and DefaultMaskingService. Not published to NuGet. |
| Json.Masker.Newtonsoft | ContractResolver that wraps sensitive members before serialization. |
| Json.Masker.SystemTextJson | JsonTypeInfo modifier that injects masking converters for System.Text.Json. |
| Json.Masker.AspNet | Middleware and helpers for toggling masking per request (System.Text.Json). |
| Json.Masker.AspNet.Newtonsoft | ASP.NET Core middleware integration for Newtonsoft.Json. |
Quick Start
Install the package for your serializer:
dotnet add package Json.Masker.Newtonsoft
# or
dotnet add package Json.Masker.SystemTextJson
# optional ASP.NET helpers
dotnet add package Json.Masker.AspNet
dotnet add package Json.Masker.AspNet.Newtonsoft
The ASP.NET helpers let you toggle masking per request with zero boilerplate.
Setup
Option 1: Dependency Injection
builder.Services.AddJsonMasking(options =>
{
// Replace with a custom IMaskingService if needed
options.MaskingService = new DefaultMaskingService();
});
builder.Services
.AddOptions<MvcNewtonsoftJsonOptions>()
.Configure<IJsonMaskingConfigurator>((opts, configurator) =>
configurator.Configure(opts.SerializerSettings));
app.UseNewtonsoftJsonMasking();
Swap Newtonsoft for System.Text.Json as needed:
builder.Services.AddControllers();
builder.Services.AddJsonMasking();
builder.Services
.AddOptions<JsonOptions>()
.Configure<IJsonMaskingConfigurator>((opts, configurator) =>
configurator.Configure(opts.SerializerOptions));
app.UseTextJsonMasking();
DI automatically registers:
IMaskingService(default or custom)IJsonMaskingConfigurator(serializer-specific configurator)
Option 2: Manual Setup
Newtonsoft.Json
var masking = new DefaultMaskingService();
var settings = new JsonSerializerSettings
{
ContractResolver = new MaskingContractResolver(masking)
};
var json = JsonConvert.SerializeObject(customer, Formatting.Indented, settings);
System.Text.Json
var masking = new DefaultMaskingService();
var options = new JsonSerializerOptions
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver
{
Modifiers = { new MaskingTypeInfoModifier(masking).Modify }
}
};
var json = JsonSerializer.Serialize(customer, options);
Masking Example
public class Customer
{
public string Name { get; set; } = string.Empty;
[Sensitive(MaskingStrategy.Creditcard)]
public string CreditCard { get; set; } = string.Empty;
[Sensitive(MaskingStrategy.Ssn)]
public string SSN { get; set; } = string.Empty;
[Sensitive(MaskingStrategy.Email)]
public string Email { get; set; } = string.Empty;
[Sensitive(MaskingStrategy.Iban)]
public string BankAccount { get; set; } = string.Empty;
[Sensitive] public int Age { get; set; }
[Sensitive(MaskingStrategy.Redacted)]
public List<string> Hobbies { get; set; } = [];
[Sensitive("##-****-####")]
public string LoyaltyNumber { get; set; } = string.Empty;
}
Enable masking for the current scope:
MaskingContextAccessor.Set(new MaskingContext { Enabled = true });
Result:
{
"Name": "Alice",
"CreditCard": "****-****-****-1234",
"SSN": "***-**-6789",
"Email": "a*****@g****.com",
"BankAccount": "GB** **** **** **** 1234",
"Age": "****",
"Hobbies": ["<redacted>", "<redacted>"],
"LoyaltyNumber": "12-****-3456"
}
Masking Strategies
| Strategy | Example Output |
|---|---|
Default |
**** |
Creditcard |
****-****-****-1234 |
Ssn |
***-**-6789 |
Redacted |
<redacted> |
Email |
a*****@d****.com |
Iban |
GB** **** **** **** 1234 |
Custom masking logic? Implement IMaskingService and register it via MaskingOptions.
Contributing
dotnet restore,dotnet build,dotnet test- Run
./install-dependencies.shto sync the expected .NET SDK and git hooks. - Run
./run-pre-commit.shto check analyzers and formatters. - Open a PR with conventional commits; merging to
maintriggers NuGet release.
Extending Masking
To add a new masking rule:
- Implement
IMaskingServiceor subclassDefaultMaskingService. - Add tests under
tests/Json.Masker.Tests. - (Optional) Contribute back via a new
MaskingStrategyvalue.
Adding Serializer Support
To integrate another serializer:
- Create a project under
src/referencingJson.Masker.Abstract. - Implement
IJsonMaskingConfigurator. - Expose an
AddJsonMaskingextension. - Add integration tests to ensure sensitive data is masked.
Performance
| Method | Mean | Allocated | Ratio |
|---|---|---|---|
| Plain_SystemTextJson | 501 ns | 752 B | 1.00 |
| JsonMasker_Newtonsoft | 990 ns | 2,152 B | 1.97 |
| JsonMasker_SystemTextJson | 801 ns | 648 B | 1.62 |
| JsonDataMasking_Newtonsoft | 8,085 ns | 6,761 B | 16.08 |
| JsonMasking_PayloadMasking | 7,013 ns | 5,720 B | 13.90 |
| Byndyusoft_SystemTextJson | 324 ns | 232 B | 0.64 |
Build & Test
dotnet restore
dotnet build
dotnet test
Run ./install-dependencies.sh to install matching SDKs and pre-commit hooks.
Samples
Check out /samples for minimal demos:
- System.Text.Json:
Json.Masker.Sample.SystemTextJson - Newtonsoft.Json:
Json.Masker.Sample.Newtonsoft
Run with:
dotnet run --project <sample-project>
View masked and unmasked outputs side-by-side in your favorite REST client. Note: in order to see masked output make sure to include 'X-Json-Mask: true' in the request headers.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Json.Masker.Abstract (>= 1.1.14)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.IO.RecyclableMemoryStream (>= 3.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.14 | 148 | 10/17/2025 |
| 1.1.11 | 184 | 10/16/2025 |
| 1.1.9 | 195 | 10/16/2025 |
| 1.1.7 | 177 | 10/16/2025 |
| 1.1.5 | 182 | 10/16/2025 |
| 1.1.3 | 188 | 10/16/2025 |
| 1.1.1 | 187 | 10/13/2025 |
| 1.0.7 | 184 | 10/13/2025 |
| 1.0.5 | 193 | 10/12/2025 |
| 1.0.3 | 186 | 10/12/2025 |
| 1.0.0 | 188 | 10/12/2025 |
| 0.5.5 | 124 | 10/10/2025 |
| 0.5.3 | 120 | 10/10/2025 |
| 0.5.1 | 115 | 10/10/2025 |
| 0.5.0 | 121 | 10/10/2025 |
| 0.4.10 | 158 | 10/10/2025 |
| 0.4.6 | 172 | 10/10/2025 |
| 0.4.4 | 166 | 10/10/2025 |
| 0.4.2 | 163 | 10/10/2025 |
| 0.4.0 | 193 | 10/10/2025 |
See the changelog at https://github.com/myarichuk/Json.Masker/blob/main/CHANGELOG.md