dotnet-localization
Comprehensive resource for .NET localization, including resource files, IStringLocalizer patterns, and cultural formatting.
Install
mkdir -p .claude/skills/dotnet-localization && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13902" && unzip -o skill.zip -d .claude/skills/dotnet-localization && rm skill.zipInstalls to .claude/skills/dotnet-localization
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Localizes .NET apps. .resx resources, IStringLocalizer, source generators, pluralization, RTL.Key capabilities
- →Manage .resx resource files and satellite assemblies
- →Implement IStringLocalizer patterns
- →Use JSON-based resources for localization
- →Apply source generators for AOT compatibility
- →Format dates, numbers, and currencies with CultureInfo
- →Support RTL layout in Blazor, MAUI, Uno Platform, and WPF
How it works
The skill provides complete guidance on .NET internationalization and localization, covering .resx files, IStringLocalizer, modern alternatives like JSON resources and source generators, and culture-specific formatting. It also addresses RTL layout support across various frameworks.
Inputs & outputs
When to use dotnet-localization
- →Localizing a .NET app
- →Implementing IStringLocalizer
- →Formatting dates for specific cultures
- →Configuring RTL layout support
About this skill
dotnet-localization
Comprehensive .NET internationalization and localization: .resx resource files and satellite assemblies, modern alternatives (JSON resources, source generators for AOT), IStringLocalizer patterns, date/number/currency formatting with CultureInfo, RTL layout support, pluralization engines, and per-framework localization integration for Blazor, MAUI, Uno Platform, and WPF.
Version assumptions: .NET 8.0+ baseline. IStringLocalizer stable since .NET Core 1.0; localization APIs stable since .NET 5. .NET 9+ features explicitly marked.
Scope
- .resx resource files, satellite assemblies, culture fallback chains
- IStringLocalizer patterns and DI registration
- Modern alternatives: JSON resources, source generators for AOT
- Date/number/currency formatting with CultureInfo
- RTL layout support per framework (Blazor, MAUI, Uno, WPF)
- Pluralization engines (MessageFormat.NET, SmartFormat.NET)
Out of scope
- Deep Blazor component patterns -- see [skill:dotnet-blazor-components]
- Deep MAUI development patterns -- see [skill:dotnet-maui-development]
- Uno Platform project structure and Extensions ecosystem -- see [skill:dotnet-uno-platform]
- WPF Host builder and MVVM patterns -- see [skill:dotnet-wpf-modern]
- Source generator authoring (Roslyn API) -- see [skill:dotnet-csharp-source-generators]
Cross-references: [skill:dotnet-blazor-components] for Blazor component lifecycle, [skill:dotnet-maui-development] for MAUI app structure, [skill:dotnet-uno-platform] for Uno Extensions and x:Uid, [skill:dotnet-wpf-modern] for WPF on modern .NET.
.resx Resource Files
Overview
Resource files (.resx) are the standard .NET localization format. They compile into satellite assemblies resolved by
ResourceManager with automatic culture fallback.
Culture Fallback Chain
Resources resolve in order of specificity, falling back until a match is found:
sr-Cyrl-RS.resx -> sr-Cyrl.resx -> sr.resx -> Resources.resx (default/neutral)
```text
The default `.resx` file (no culture suffix) is the single source of truth. Translation files must not contain keys
absent from the default file.
### Project Setup
```xml
<!-- MyApp.csproj -->
<PropertyGroup>
<NeutralLanguage>en-US</NeutralLanguage>
</PropertyGroup>
<ItemGroup>
<!-- Default resources -->
<EmbeddedResource Include="Resources\Messages.resx" />
<!-- Culture-specific resources -->
<EmbeddedResource Include="Resources\Messages.fr-FR.resx" />
<EmbeddedResource Include="Resources\Messages.de-DE.resx" />
</ItemGroup>
```text
### Resource File Structure
```xml
<!-- Resources/Messages.resx (default/neutral) -->
<?xml version="1.0" encoding="utf-8"?>
<root>
<data name="Welcome" xml:space="preserve">
<value>Welcome to the application</value>
<comment>Shown on the home page</comment>
</data>
<data name="ItemCount" xml:space="preserve">
<value>You have {0} item(s)</value>
<comment>{0} = number of items</comment>
</data>
</root>
```text
### Accessing Resources
```csharp
// Via generated strongly-typed class (ResXFileCodeGenerator custom tool)
string welcome = Messages.Welcome;
// Via ResourceManager directly
var rm = new ResourceManager("MyApp.Resources.Messages",
typeof(Messages).Assembly);
string welcome = rm.GetString("Welcome", CultureInfo.CurrentUICulture);
```text
---
## Modern Alternatives
### JSON-Based Resources
Lightweight alternative for projects already using JSON for configuration. Libraries provide `IStringLocalizer`
implementations backed by JSON files.
```json
// Resources/en-US.json
{
"Welcome": "Welcome to the application",
"ItemCount": "You have {0} item(s)"
}
```text
**Libraries:**
- `Senlin.Mo.Localization` -- JSON-backed `IStringLocalizer`
- `Embedded.Json.Localization` -- embedded JSON resources
JSON resources are popular in ASP.NET Core but lack the built-in tooling support (Visual Studio designer, satellite
assembly compilation) of `.resx`.
### Source Generators for AOT Compatibility
Traditional `.resx` with `ResourceManager` uses reflection at runtime, which is problematic for Native AOT and trimming.
Source generators eliminate runtime reflection by generating strongly-typed accessor classes at compile time.
**Recommended source generators:**
| Generator | Description | AOT-Safe |
| -------------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| ResXGenerator (ycanardeau) | Strongly-typed classes with `IStringLocalizer` support and DI registration | Yes |
| VocaDb.ResXFileCodeGenerator | Original strongly-typed `.resx` source generator | Yes |
| Built-in `ResXFileCodeGenerator` | Visual Studio custom tool (not a Roslyn source generator) | No -- generates static properties but still uses `ResourceManager` |
```xml
<!-- Using ResXGenerator -->
<ItemGroup>
<PackageReference Include="ResXGenerator" Version="1.*"
PrivateAssets="all" />
</ItemGroup>
```text
```csharp
// Generated at compile time -- no runtime reflection
string welcome = Messages.Welcome;
// With DI registration (ResXGenerator)
services.AddResXLocalization();
```text
**Recommendation:** Use `.resx` files as the resource format (broadest tooling support) with a source generator for
AOT/trimming scenarios. Use JSON resources only for lightweight or config-heavy projects.
---
## IStringLocalizer Patterns
### Registration
```csharp
var builder = WebApplication.CreateBuilder(args);
// Register localization services
builder.Services.AddLocalization(options =>
options.ResourcesPath = "Resources");
var app = builder.Build();
// Configure request localization middleware
var supportedCultures = new[] { "en-US", "fr-FR", "de-DE", "ja-JP" };
app.UseRequestLocalization(options =>
{
options.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
});
```text
### IStringLocalizer<T>
The primary localization interface. Injectable via DI. Use everywhere: services, controllers, Blazor components,
middleware.
```csharp
public class OrderService
{
private readonly IStringLocalizer<OrderService> _localizer;
public OrderService(IStringLocalizer<OrderService> localizer)
{
_localizer = localizer;
}
public string GetConfirmation(int orderId)
{
// Indexer returns LocalizedString with implicit string conversion
return _localizer["OrderConfirmed", orderId];
// Resolves: "Order {0} confirmed" with orderId substituted
}
public bool IsTranslated(string key)
{
LocalizedString result = _localizer[key];
return !result.ResourceNotFound;
}
}
```text
### IViewLocalizer (MVC Razor Views Only)
Auto-resolves resource files matching the view path. Not supported in Blazor.
```cshtml
@* Views/Home/Index.cshtml *@
@inject IViewLocalizer Localizer
<h1>@Localizer["Welcome"]</h1>
<p>@Localizer["ItemCount", Model.Count]</p>
```text
Resource file location: `Resources/Views/Home/Index.en-US.resx`
### IHtmlLocalizer (MVC Only)
HTML-aware variant that HTML-encodes format arguments but preserves HTML in the resource string itself. Not supported in
Blazor.
```cshtml
@inject IHtmlLocalizer<SharedResource> HtmlLocalizer
@* Resource: "Read our <a href='/terms'>terms</a>, {0}" *@
@* {0} is HTML-encoded, the <a> tag is preserved *@
<p>@HtmlLocalizer["TermsNotice", Model.UserName]</p>
```text
### When to Use Each
| Interface | Scope | HTML-Safe | Blazor | MVC |
| --------------------- | ------------------ | --------------- | ------ | --- |
| `IStringLocalizer<T>` | Everywhere | No (plain text) | Yes | Yes |
| `IViewLocalizer` | View-local strings | No | **No** | Yes |
| `IHtmlLocalizer<T>` | HTML in resources | Yes | **No** | Yes |
### Namespace Resolution
If resource lookup fails, check namespace alignment. `IStringLocalizer<T>` resolves resources using the full type name
of `T` relative to the `ResourcesPath`. Use `RootNamespaceAttribute` to fix namespace/assembly mismatches:
```csharp
[assembly: RootNamespace("MyApp")]
```csharp
---
## Date, Number, and Currency Formatting
### CultureInfo
`CultureInfo` is the central class for culture-specific formatting. Two distinct properties control behavior:
- `CultureInfo.CurrentCulture` -- controls **formatting** (dates, numbers, currency)
- `CultureInfo.CurrentUICulture` -- controls **resource lookup** (which `.resx` file)
```csharp
// Always pass explicit CultureInfo -- never rely on thread defaults in server code
var date = DateTime.Now.ToString("D", new CultureInfo("fr-FR"));
// "vendredi 14 fevrier 2026"
var price = 1234.56m.ToString("C", new CultureInfo("de-DE"));
// "1.234,56 EUR" (uses NumberFormatInfo.CurrencySymbol)
var number = 1234567.89.ToString("N2", new CultureInfo("ja-JP"));
// "1,234,567.89"
```text
### Server-Side Best Practices
```csharp
// Use useUserOverride: false in server scenarios to avoid
// picking up user-customized formats
var culture = new CultureInfo("en-US", useUserOverride: false);
// Set culture per-request (ASP.NET Core middleware handles this)
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
```text
### Format Specifiers
| Specifier | Type | Example (en-US) | Example (de-DE) |
| --------- | ---------- | ------------------------- | ------------------------- |
| `"d"` | Short date | 2/14/2026 | 14.02.2026
---
*Content truncated.*
When not to use it
- →The task requires deep MAUI development patterns
- →The task requires Uno Platform project structure and Extensions ecosystem
Limitations
- →Assumes a .NET 8.0+ baseline
- →Out of scope for deep Blazor component patterns, MAUI development patterns, Uno Platform project structure, WPF Host builder and MVVM patterns, or source generator authoring
- →ResourceManager uses reflection at runtime, which is problematic for Native AOT and trimming
How it compares
This skill offers detailed, framework-specific guidance for .NET localization, including modern AOT-compatible approaches, which is more specialized than general localization advice.
Compared to similar skills
dotnet-localization side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| dotnet-localization (this skill) | 0 | 5mo | No flags | Intermediate |
| localization | 0 | 5mo | No flags | Beginner |
| microsoft-code-reference | 7 | 5mo | Review | Beginner |
| microsoft-skill-creator | 6 | 4mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by rudironsoni
View all by rudironsoni →You might also like
localization
Develop4Us-Company
Instructions for managing localization and resource files in the AppProject .NET template. Covers adding translation keys to .resx files, resource key naming conventions, placeholder formatting, and maintaining consistency across en-US, pt-BR, and es-ES translations. Use when the user needs to add o
microsoft-code-reference
github
Look up Microsoft API references, find working code samples, and verify SDK code is correct. Use when working with Azure SDKs, .NET libraries, or Microsoft APIs—to find the right method, check parameters, get working examples, or troubleshoot errors. Catches hallucinated methods, wrong signatures, and deprecated patterns by querying official docs.
microsoft-skill-creator
MicrosoftDocs
Create agent skills for Microsoft technologies using Learn MCP tools. Use when users want to create a skill that teaches agents about any Microsoft technology, library, framework, or service (Azure, .NET, M365, VS Code, Bicep, etc.). Investigates topics deeply, then generates a hybrid skill storing essential knowledge locally while enabling dynamic deeper investigation.
connection-properties
dotnet
Specialized agent for creating and improving Connection Properties in Aspire resource and README files
agui-dotnet-feature-workflow
ag-ui-protocol
>
microsoft-docs
SilverPham08091998
Understand Microsoft technologies by querying official documentation. Use whenever the user asks how something works, wants tutorials, needs configuration options, limits, quotas, or best practices for any Microsoft technology (Azure, .NET, M365, Windows, Power Platform, etc.)—even if they don't men