![]() |
VOOZH | about |
dotnet add package I-Synergy.Framework.AspNetCore.Globalization --version 2026.10618.11733
NuGet\Install-Package I-Synergy.Framework.AspNetCore.Globalization -Version 2026.10618.11733
<PackageReference Include="I-Synergy.Framework.AspNetCore.Globalization" Version="2026.10618.11733" />
<PackageVersion Include="I-Synergy.Framework.AspNetCore.Globalization" Version="2026.10618.11733" />Directory.Packages.props
<PackageReference Include="I-Synergy.Framework.AspNetCore.Globalization" />Project file
paket add I-Synergy.Framework.AspNetCore.Globalization --version 2026.10618.11733
#r "nuget: I-Synergy.Framework.AspNetCore.Globalization, 2026.10618.11733"
#:package I-Synergy.Framework.AspNetCore.Globalization@2026.10618.11733
#addin nuget:?package=I-Synergy.Framework.AspNetCore.Globalization&version=2026.10618.11733Install as a Cake Addin
#tool nuget:?package=I-Synergy.Framework.AspNetCore.Globalization&version=2026.10618.11733Install as a Cake Tool
Comprehensive globalization and localization support for ASP.NET Core applications. This package provides request culture providers, route-based culture resolution, language services, and seamless integration with ASP.NET Core's localization middleware.
π NuGet
π License
π .NET
Install the package via NuGet:
dotnet add package I-Synergy.Framework.AspNetCore.Globalization
In your Program.cs:
using ISynergy.Framework.AspNetCore.Globalization.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add globalization services
builder.AddGlobalization();
builder.Services.AddControllers();
var app = builder.Build();
// Use request localization middleware
app.UseRequestLocalization();
app.MapControllers();
app.Run();
In your appsettings.json:
{
"GlobalizationOptions": {
"DefaultCulture": "en-US",
"SupportedCultures": [
"en-US",
"nl-NL",
"de-DE",
"fr-FR",
"es-ES"
],
"ProviderType": "Route"
}
}
For route-based culture resolution, update your routing:
using ISynergy.Framework.AspNetCore.Globalization.Constraints;
var builder = WebApplication.CreateBuilder(args);
builder.AddGlobalization();
builder.Services.AddControllers();
var app = builder.Build();
app.UseRequestLocalization();
// Map controllers with culture route constraint
app.MapControllerRoute(
name: "default",
pattern: "{culture:culture}/{controller=Home}/{action=Index}/{id?}");
app.MapControllerRoute(
name: "fallback",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Access localized resources in your code:
using ISynergy.Framework.Core.Abstractions.Services;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("{culture:culture}/api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly ILanguageService _languageService;
public ProductsController(ILanguageService languageService)
{
_languageService = languageService;
}
[HttpGet]
public IActionResult GetProducts()
{
var welcomeMessage = _languageService.GetString("WelcomeMessage");
var productsTitle = _languageService.GetString("ProductsTitle");
return Ok(new
{
Message = welcomeMessage,
Title = productsTitle
});
}
}
ISynergy.Framework.AspNetCore.Globalization.Options/
βββ GlobalizationOptions # Configuration for cultures and providers
ISynergy.Framework.AspNetCore.Globalization.Providers/
βββ RouteDataRequestCultureProvider # Extract culture from route data
ISynergy.Framework.AspNetCore.Globalization.Constraints/
βββ CultureRouteConstraint # Validate culture in route segments
ISynergy.Framework.AspNetCore.Globalization.Services/
βββ LanguageService # Access localized resources
ISynergy.Framework.AspNetCore.Globalization.Enumerations/
βββ RequestCultureProviderTypes # Available provider types
Configure different provider types based on your application needs:
{
"GlobalizationOptions": {
"DefaultCulture": "en-US",
"SupportedCultures": ["en-US", "nl-NL", "de-DE"],
"ProviderType": "Route"
}
}
Available provider types:
/nl-NL/products)?culture=nl-NL)Define culture-aware routes in your controllers:
using Microsoft.AspNetCore.Mvc;
[Route("{culture:culture}/[controller]")]
[ApiController]
public class LocalizedController : ControllerBase
{
// URL: /nl-NL/localized/hello
[HttpGet("hello")]
public IActionResult Hello()
{
var culture = RouteData.Values["culture"]?.ToString();
return Ok($"Hello in culture: {culture}");
}
}
[Route("[controller]")]
[ApiController]
public class NonLocalizedController : ControllerBase
{
// URL: /nonlocalized/hello (uses default culture)
[HttpGet("hello")]
public IActionResult Hello()
{
return Ok("Hello");
}
}
Set or override culture programmatically:
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class CultureController : ControllerBase
{
[HttpPost("set")]
public IActionResult SetCulture([FromBody] string culture)
{
// Set culture cookie
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture)),
new CookieOptions
{
Expires = DateTimeOffset.UtcNow.AddYears(1),
IsEssential = true,
SameSite = SameSiteMode.Lax
});
return Ok($"Culture set to: {culture}");
}
[HttpGet("current")]
public IActionResult GetCulture()
{
var feature = HttpContext.Features.Get<IRequestCultureFeature>();
var culture = feature?.RequestCulture.Culture.Name ?? "Unknown";
var uiCulture = feature?.RequestCulture.UICulture.Name ?? "Unknown";
return Ok(new
{
Culture = culture,
UICulture = uiCulture
});
}
}
Configure localized resources for your application:
using ISynergy.Framework.Core.Abstractions.Services;
// In your Program.cs or startup configuration
var languageService = builder.Services
.BuildServiceProvider()
.GetRequiredService<ILanguageService>();
// Add resource managers for different assemblies
languageService.AddResourceManager(typeof(AppResources));
languageService.AddResourceManager(typeof(SharedResources));
languageService.AddResourceManager(typeof(ValidationResources));
Create resource files for each supported culture:
Resources/AppResources.resx (default/English)Resources/AppResources.nl-NL.resx (Dutch)Resources/AppResources.de-DE.resx (German)Access resources:
using ISynergy.Framework.Core.Abstractions.Services;
public class LocalizedService
{
private readonly ILanguageService _languageService;
public LocalizedService(ILanguageService languageService)
{
_languageService = languageService;
}
public string GetLocalizedMessage(string key)
{
return _languageService.GetString(key);
}
public string GetLocalizedMessageWithFormat(string key, params object[] args)
{
var format = _languageService.GetString(key);
return string.Format(format, args);
}
}
Complete example of a multi-language e-commerce API:
using ISynergy.Framework.AspNetCore.Globalization.Extensions;
using ISynergy.Framework.Core.Abstractions.Services;
using Microsoft.AspNetCore.Localization;
var builder = WebApplication.CreateBuilder(args);
// Add globalization
builder.AddGlobalization();
builder.Services.AddControllers();
var app = builder.Build();
// Configure request localization
var localizationOptions = app.Services
.GetRequiredService<IOptions<RequestLocalizationOptions>>()
.Value;
app.UseRequestLocalization(localizationOptions);
// Route configuration with culture
app.MapControllerRoute(
name: "localized",
pattern: "{culture:culture}/{controller=Home}/{action=Index}/{id?}");
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
// Product Controller
[Route("{culture:culture}/api/[controller]")]
[ApiController]
public class ProductsController : ControllerBase
{
private readonly ILanguageService _languageService;
private readonly IProductRepository _productRepository;
public ProductsController(
ILanguageService languageService,
IProductRepository productRepository)
{
_languageService = languageService;
_productRepository = productRepository;
}
[HttpGet]
public IActionResult GetProducts()
{
var products = _productRepository.GetAll();
return Ok(new
{
Title = _languageService.GetString("Products_Title"),
Description = _languageService.GetString("Products_Description"),
Items = products
});
}
[HttpGet("{id}")]
public IActionResult GetProduct(int id)
{
var product = _productRepository.GetById(id);
if (product == null)
{
return NotFound(new
{
Error = _languageService.GetString("Product_NotFound")
});
}
return Ok(product);
}
[HttpPost]
public IActionResult CreateProduct([FromBody] ProductDto productDto)
{
if (!ModelState.IsValid)
{
return BadRequest(new
{
Error = _languageService.GetString("Validation_Failed"),
Errors = ModelState
});
}
var product = _productRepository.Create(productDto);
return CreatedAtAction(
nameof(GetProduct),
new { id = product.Id },
product);
}
}
// Program.cs
using ISynergy.Framework.AspNetCore.Globalization.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.AddGlobalization();
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
var app = builder.Build();
app.UseRequestLocalization();
app.UseStaticFiles();
app.UseRouting();
app.MapBlazorHub();
app.MapFallbackToPage("/{culture:culture}/_Host");
app.MapFallbackToPage("/_Host");
app.Run();
@page "/{culture?}"
@using Microsoft.AspNetCore.Localization
@{
var culture = RouteData.Values["culture"]?.ToString() ?? "en-US";
var requestCulture = new RequestCulture(culture);
Context.Features.Set<IRequestCultureFeature>(
new RequestCultureFeature(requestCulture, null));
}
<!DOCTYPE html>
<html lang="@culture">
<head>
<meta charset="utf-8" />
<title>My App - @culture</title>
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
</body>
</html>
@inject ILanguageService LanguageService
@inject NavigationManager Navigation
<div class="culture-switcher">
<label>@LanguageService.GetString("SelectLanguage")</label>
<select @onchange="OnCultureChanged">
<option value="en-US" selected="@(CurrentCulture == "en-US")">English</option>
<option value="nl-NL" selected="@(CurrentCulture == "nl-NL")">Nederlands</option>
<option value="de-DE" selected="@(CurrentCulture == "de-DE")">Deutsch</option>
<option value="fr-FR" selected="@(CurrentCulture == "fr-FR")">FranΓ§ais</option>
<option value="es-ES" selected="@(CurrentCulture == "es-ES")">EspaΓ±ol</option>
</select>
</div>
@code {
private string CurrentCulture { get; set; } = "en-US";
protected override void OnInitialized()
{
var uri = new Uri(Navigation.Uri);
var segments = uri.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (segments.Length > 0)
{
CurrentCulture = segments[0];
}
}
private void OnCultureChanged(ChangeEventArgs e)
{
var newCulture = e.Value?.ToString() ?? "en-US";
var uri = new Uri(Navigation.Uri);
var path = uri.AbsolutePath;
// Remove current culture from path if present
var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (segments.Length > 0 && IsSupportedCulture(segments[0]))
{
path = "/" + string.Join("/", segments.Skip(1));
}
// Redirect to new culture
var newUri = $"/{newCulture}{path}{uri.Query}";
Navigation.NavigateTo(newUri, forceLoad: true);
}
private bool IsSupportedCulture(string culture)
{
var supported = new[] { "en-US", "nl-NL", "de-DE", "fr-FR", "es-ES" };
return supported.Contains(culture);
}
}
Use route-based culture for SEO-friendly URLs and better user experience with language-specific content.
Always configure a default culture to fall back to when the requested culture is not supported.
Test your application with right-to-left (RTL) languages if you plan to support them (e.g., Arabic, Hebrew).
/{culture}/products)Example unit tests for globalization:
using ISynergy.Framework.AspNetCore.Globalization.Providers;
using ISynergy.Framework.AspNetCore.Globalization.Options;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using Xunit;
public class RouteDataRequestCultureProviderTests
{
[Fact]
public async Task DetermineProviderCultureResult_WithValidCulture_ReturnsCulture()
{
// Arrange
var options = Options.Create(new GlobalizationOptions
{
DefaultCulture = "en-US",
SupportedCultures = new[] { "en-US", "nl-NL" }
});
var provider = new RouteDataRequestCultureProvider(options);
var context = new DefaultHttpContext();
context.Request.Path = "/nl-NL/products";
// Act
var result = await provider.DetermineProviderCultureResult(context);
// Assert
Assert.NotNull(result);
Assert.Equal("nl-NL", result.Cultures.First().Value);
}
[Fact]
public async Task DetermineProviderCultureResult_WithInvalidCulture_ReturnsDefault()
{
// Arrange
var options = Options.Create(new GlobalizationOptions
{
DefaultCulture = "en-US",
SupportedCultures = new[] { "en-US", "nl-NL" }
});
var provider = new RouteDataRequestCultureProvider(options);
var context = new DefaultHttpContext();
context.Request.Path = "/invalid/products";
// Act
var result = await provider.DetermineProviderCultureResult(context);
// Assert
Assert.NotNull(result);
Assert.Equal("en-US", result.Cultures.First().Value);
}
}
For more information about the I-Synergy Framework:
For issues, questions, or contributions, please visit the GitHub repository.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.10618.11733 | 0 | 6/18/2026 |
| 2026.10618.11702-preview | 0 | 6/18/2026 |
| 2026.10616.12121 | 71 | 6/16/2026 |
| 2026.10616.11904-preview | 42 | 6/16/2026 |
| 2026.10616.10010 | 71 | 6/15/2026 |
| 2026.10615.12240-preview | 75 | 6/15/2026 |
| 2026.10615.10047-preview | 80 | 6/14/2026 |
| 2026.10614.10112-preview | 91 | 6/13/2026 |
| 2026.10612.12341-preview | 98 | 6/12/2026 |
| 2026.10612.12110-preview | 82 | 6/12/2026 |
| 2026.10612.11941-preview | 86 | 6/12/2026 |
| 2026.10610.10831 | 91 | 6/10/2026 |
| 2026.10610.10706-preview-pr... | 83 | 6/10/2026 |
| 2026.10609.11323-preview | 83 | 6/9/2026 |
| 2026.10607.11905-preview | 89 | 6/7/2026 |
| 2026.10607.11454-preview | 94 | 6/7/2026 |
| 2026.10606.11854-preview | 92 | 6/6/2026 |
| 2026.10603.11238-preview | 94 | 6/3/2026 |
| 2026.10602.12203-preview | 92 | 6/2/2026 |
| 2026.10602.11949-preview | 89 | 6/2/2026 |