ASP.NET Core  

Handling Multi-Language Content in REST APIs | ASP.NET Core

Introduction

In today’s globalized digital ecosystem, web applications and APIs must cater to users across multiple countries, cultures, and languages. Whether you’re building a content management system, an e-commerce site, or a customer support portal, multi-language (or localization) support is no longer optional — it’s essential.

In this article, we’ll learn how to handle multi-language content in REST APIs using ASP.NET Core, with clear examples, architecture workflow, and best practices to maintain clean, scalable localization logic.

What is Multi-Language Content Handling?

Multi-language content handling means your API can serve the same data in different languages based on user preferences or system configuration.

For example

GET /api/products/101?lang=en  
→ { "id": 101, "name": "Wireless Mouse" }

GET /api/products/101?lang=fr  
→ { "id": 101, "name": "Souris sans fil" }

The key goal is to separate content from language, making the system easy to scale and maintain.

Technical Workflow (Flowchart)

flowchart TD
A[Client Request with 'lang' Parameter] --> B[API Middleware Detects Language]
B --> C[Load Language Resource (DB or JSON file)]
C --> D[Fetch Content in Preferred Language]
D --> E[Fallback to Default Language if Not Found]
E --> F[Return Localized JSON Response]

Approaches for Multi-Language Content

There are two common strategies to handle multi-language content in APIs:

1. Database Localization

You store content in multiple languages in the database.

Example Table

ProductIdLanguageNameDescription
101enWireless MouseErgonomic mouse design
101frSouris sans filSouris ergonomique

Pros

  • Centralized management

  • Easy to update via admin panel

  • Good for dynamic content

Cons

  • Slightly complex queries

  • Needs proper caching

2. File-Based Localization (Resource Files)

For static text (like labels, validation messages, etc.), use .resx or JSON resource files.

Example

/Resources
  ├── SharedResources.en.json
  ├── SharedResources.fr.json

SharedResources.en.json

{"Welcome": "Welcome to our application!","Logout": "Logout"}

SharedResources.fr.json

{"Welcome": "Bienvenue dans notre application!","Logout": "Se déconnecter"}

Step-by-Step Implementation in ASP.NET Core

Step 1: Add Localization Dependencies

Add this package to your project:

dotnet add package Microsoft.Extensions.Localization

Step 2: Configure Localization in Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[] { "en", "fr", "de", "hi" };
    options.SetDefaultCulture("en");
    options.AddSupportedCultures(supportedCultures);
    options.AddSupportedUICultures(supportedCultures);
});

builder.Services.AddControllers();

var app = builder.Build();

var localizationOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(localizationOptions.Value);

app.MapControllers();
app.Run();

Step 3: Create a Resource File

Create a folder named Resources and add the following files:

  • Controllers.HomeController.en.resx

  • Controllers.HomeController.fr.resx

HomeController.en.resx

NameValue
WelcomeMessageWelcome to the API!

HomeController.fr.resx

NameValue
WelcomeMessageBienvenue sur l'API!

Step 4: Use Localizer in Controller

using Microsoft.Extensions.Localization;
using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
[ApiController]
public class HomeController : ControllerBase
{
    private readonly IStringLocalizer<HomeController> _localizer;

    public HomeController(IStringLocalizer<HomeController> localizer)
    {
        _localizer = localizer;
    }

    [HttpGet("welcome")]
    public IActionResult GetWelcomeMessage()
    {
        var message = _localizer["WelcomeMessage"];
        return Ok(new { message });
    }
}

Now call the API with header:

Accept-Language: fr

Response:

{"message": "Bienvenue sur l'API!"}

Step 5: Multi-Language Content from Database

If your content is dynamic (e.g., product names), structure your database like this:

CREATE TABLE Product (
  Id INT PRIMARY KEY,
  DefaultName NVARCHAR(200)
);

CREATE TABLE ProductTranslation (
  ProductId INT,
  LanguageCode NVARCHAR(10),
  Name NVARCHAR(200),
  Description NVARCHAR(1000)
);

Sample Query

SELECT p.Id, 
       ISNULL(pt.Name, p.DefaultName) AS Name
FROM Product p
LEFT JOIN ProductTranslation pt 
ON p.Id = pt.ProductId AND pt.LanguageCode = @Lang

Handling Fallback Languages

Always include a fallback mechanism if a translation doesn’t exist.

Example in C#:

string localizedText = translations.FirstOrDefault(t => t.Language == lang)?.Text 
                       ?? translations.FirstOrDefault(t => t.Language == "en")?.Text;

Combining API + Angular Frontend

  • Angular sends a lang parameter or Accept-Language header.

  • API reads it and sends localized content.

  • Angular translates UI labels using ngx-translate while data (from API) comes already localized.

Angular Service Example

getProductDetails(id: number, lang: string): Observable<Product> {
  return this.http.get<Product>(`/api/products/${id}?lang=${lang}`);
}

Performance Optimization Tips

  1. Cache Translations
    Use IMemoryCache or Redis for frequent translations.

  2. Batch Translations
    Load all localized fields in one query.

  3. Avoid Overfetching
    Only return localized fields required by the frontend.

  4. Async Resource Loading
    When using .resx, preload resource dictionaries asynchronously.

Common Accessibility and Localization Audit Checklist

AreaDescription
Content SeparationText is not hardcoded in API responses
Default LanguageSystem falls back to English or configured language
UTF-8 SupportDatabase and API both handle UTF-8 encoding
Dynamic LocalizationAPI can handle runtime changes in preferred language
Header-Based LanguageSupports Accept-Language header

Conclusion

Implementing multi-language content handling in your ASP.NET Core REST APIs not only improves user experience but also opens your product to a global audience.

With resource-based localization for static text and database-driven translations for dynamic content, you can build a flexible, scalable architecture that supports any number of languages. Combine this with caching, proper culture handling, and smart fallbacks — and your API will be truly international-ready.