ASP.NET Core  

Multi-Language CRUD Project in ASP.NET Core Web API

A multi-language CRUD application allows users from different regions to:

  • View data in their own language

  • Receive localized messages

  • Use the same API with different cultures

This is commonly used in:

  • E-commerce platforms

  • Banking apps

  • Government portals

  • International SaaS products

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)

KeyValue
ProductAddedProduct added successfully
ProductUpdatedProduct updated successfully
ProductDeletedProduct deleted successfully
ProductNotFoundProduct not found

French (fr-FR)

KeyValue
ProductAddedProduit ajouté avec succès
ProductUpdatedProduit mis à jour avec succès
ProductDeletedProduit supprimé avec succès
ProductNotFoundProduit 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):

  1. Query string (?culture=fr-FR)

  2. Cookies

  3. Accept-Language header

10. Interview-Ready Questions & Answers

Q1: How do you build a multi-language API?

By enabling localization, using resource files, and selecting culture from request headers.

Q2: Where do translations live?

In .resx resource files per culture.

Q3: Can APIs return localized messages?

Yes, using IStringLocalizer.

Q4: Does localization affect data?

No, it affects messages and formatting, not stored data.

Summary

FeatureDescription
LocalizationLanguage translation
GlobalizationCulture formatting
CRUDData operations
Resource filesStore translations
Accept-LanguageSelect language