
January 6, 2026 06:35 by
Peter
Users from various locations can do the following with a multilingual CRUD application:
- See information in their native tongue
- Get messages that are localized
- Utilize the same API across cultural boundaries

This is frequently utilized in:
- Platforms for online sales
- Apps for banks
- Portals for the government
- Global SaaS offerings
1. Project Scenario (Real-World Example)
We will build a Product Management API that supports:
- English (en-US)
- French (fr-FR)
- Arabic (ar-SA)
The API will:
- Create products
- Read products
- Update products
- Delete products
Return localized messages
2. Technologies Used
- ASP.NET Core Web API
- Localization (IStringLocalizer)
- Resource files (.resx)
- In-memory data (for simplicity)
- JSON & XML formats
3. Enable Localization in ASP.NET Core
Program.cs Configuration
using Microsoft.AspNetCore.Localization;
using System.Globalization;
builder.Services.AddLocalization(options =>
{
options.ResourcesPath = "Resources";
});
builder.Services.AddControllers()
.AddXmlSerializerFormatters();
var supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("fr-FR"),
new CultureInfo("ar-SA")
};
app.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture("en-US"),
SupportedCultures = supportedCultures,
SupportedUICultures = supportedCultures
});
app.MapControllers();
app.Run();
4. Product Model
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
5. Resource Files Structure
Create a Resources folder:
Resources/
└── Controllers.ProductsController.en-US.resx
└── Controllers.ProductsController.fr-FR.resx
└── Controllers.ProductsController.ar-SA.resx
Resource Keys & Values
English (en-US)
| Key | Value |
| ProductAdded |
Product added successfully |
| ProductUpdated |
Product updated successfully |
| ProductDeleted |
Product deleted successfully |
| ProductNotFound |
Product not found |
French (fr-FR)
| Key | Value |
| ProductAdded |
Produit ajouté avec succès |
| ProductUpdated |
Produit mis à jour avec succès |
| ProductDeleted |
Produit supprimé avec succès |
| ProductNotFound |
Produit introuvable |
6. Products Controller (Localized CRUD)
using Microsoft.Extensions.Localization;
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{
private static List<Product> products = new();
private readonly IStringLocalizer<ProductsController> _localizer;
public ProductsController(IStringLocalizer<ProductsController> localizer)
{
_localizer = localizer;
}
[HttpGet]
public IActionResult GetAll()
{
return Ok(products);
}
[HttpPost]
public IActionResult Create(Product product)
{
products.Add(product);
return Ok(new
{
Message = _localizer["ProductAdded"],
Data = product
});
}
[HttpPut("{id}")]
public IActionResult Update(int id, Product updated)
{
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null)
return NotFound(_localizer["ProductNotFound"]);
product.Name = updated.Name;
product.Price = updated.Price;
return Ok(_localizer["ProductUpdated"]);
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null)
return NotFound(_localizer["ProductNotFound"]);
products.Remove(product);
return Ok(_localizer["ProductDeleted"]);
}
}
7. Testing with Different Languages
Create Product (English)
Request
POST /api/products
Accept-Language: en-US
Content-Type: application/json
{
"id": 1,
"name": "Laptop",
"price": 1200
}
Response
{
"message": "Product added successfully",
"data": {
"id": 1,
"name": "Laptop",
"price": 1200
}
}
Create Product (French)
Header
Accept-Language: fr-FR
Response
{
"message": "Produit ajouté avec succès",
"data": {
"id": 1,
"name": "Laptop",
"price": 1200
}
}
Delete Product (Arabic)
Request
DELETE /api/products/1
Accept-Language: ar-SA
Response
"تم حذف المنتج بنجاح"
8. XML Request & Response Example
XML Request
POST /api/products
Content-Type: application/xml
Accept-Language: en-US
<Product>
<Id>2</Id>
<Name>Mouse</Name>
<Price>25</Price>
</Product>
XML Response
<object>
<Message>Product added successfully</Message>
<Data>
<Id>2</Id>
<Name>Mouse</Name>
<Price>25</Price>
</Data>
</object>
9. How Culture Is Selected
ASP.NET Core checks (in order):
- Query string (?culture=fr-FR)
- Cookies
- Accept-Language header