BstTranslations 10.0.14

BstTranslations

Property-based translation system for ASP.NET Core. You define one C# class with one property per translatable string; values are loaded per culture from a backing store you control, with localizable DataAnnotations validators and an enum-translation attribute.

Setup

1. Implement ITranslation

A persisted translation row. Bring your own EF entity:

using BstTranslations.Models.Contracts;

public class Translation : ITranslation {
    public int Id { get; set; }
    public string Name { get; set; }
    public string DefaultValue { get; set; }
    public DateTimeOffset ValueUpdateTime { get; set; }

    public string ValuePt { get; set; }
    public string ValueEn { get; set; }

    public string GetValueForCulture(string cultureCode) => cultureCode switch {
        "en" => ValueEn,
        _    => ValuePt ?? DefaultValue
    };
}

2. Implement ITranslationsManager

Loads/persists translations from your storage (DB, file, etc.):

public class TranslationsManager : ITranslationsManager {
    public Task<List<ITranslation>> GetTranslations() { ... }
    public Task<ITranslation> GetTranslationByName(string name) { ... }
    public Task<ITranslation> AddTranslation(string name, string value = null) { ... }
}

3. Subclass BaseTranslationsService

One property per translation key. The default value passed to T(...) is what gets stored if the key doesn't exist yet:

public class AppTranslations(IHttpContextAccessor ctx, IServiceScopeFactory sf)
    : BaseTranslationsService(ctx, sf) {

    public HtmlString Welcome              => T("Bem-vindo");
    public HtmlString GreetingWithName     => T("Olá, {0}!");
    public HtmlString Required_Field       => T("Este campo é obrigatório");
}

4. Register

// BstLogger must already be registered.
services.AddTranslationsService<AppTranslations, TranslationsManager>(singleton: true);

singleton: true uses an in-memory cache shared across requests; false reloads per scope.

Usage

Translate in views/services

@inject AppTranslations T

<h1>@T.Welcome</h1>
<p>@T.GreetingWithName.Params(user.Name)</p>

Params() (from BstTranslations.Extensions) does string.Format on an HtmlString.

The culture is read from the culture route value (/{culture}/...). Override at runtime:

T.SetCulture("en");
T.SetDynamicCulture(true); // re-read culture from route on every T(...) call

Localizable validators

Use the Localizable* variants and pass the property name of the translation, not a literal message:

using BstTranslations.DataAnnotations.LocalizableValidators;

public class RegisterDto {
    [LocalizableRequired(nameof(AppTranslations.Required_Field))]
    [LocalizableMaxLength(50, nameof(AppTranslations.MaxLength_50))]
    public string Name { get; set; }

    [LocalizableEmailAddress(nameof(AppTranslations.Invalid_Email))]
    public string Email { get; set; }

    [LocalizableMinLength(8, nameof(AppTranslations.Password_TooShort))]
    public string Password { get; set; }

    [LocalizableCompare(nameof(Password), nameof(AppTranslations.Passwords_DoNotMatch))]
    public string PasswordConfirmation { get; set; }
}

The provided IValidationAttributeAdapterProvider resolves the property name to the current translation, both server-side and in jquery.validate unobtrusive output.

Enum translations

using BstTranslations.DataAnnotations;

public enum OrderStatus {
    [EnumWithTranslation(nameof(AppTranslations.Status_Pending))]   Pending,
    [EnumWithTranslation(nameof(AppTranslations.Status_Shipped))]   Shipped,
    [EnumWithTranslation(nameof(AppTranslations.Status_Delivered))] Delivered
}

@T.GetEnumTranslation(order.Status)

Sync translation keys to storage

TranslationsHelper.GetTranslationObjects reflects every property on your translations service into ITranslation rows so you can seed/upsert your store:

var rows = TranslationsHelper
    .GetTranslationObjects<AppTranslations, Translation>(appTranslations);
// upsert rows via your TranslationsManager / DbContext

Call T.UpdateTranslations() to refresh the in-memory cache (singleton mode) after changes.

No packages depend on BstTranslations.

.NET 10.0

Version Downloads Last updated
10.0.14 2 03/05/2026
10.0.13 3 23/04/2026
10.0.12 4 16/04/2026
10.0.11 14 06/04/2026
10.0.10 6 20/03/2026
10.0.9 4 20/03/2026
10.0.8 4 20/03/2026
10.0.7 4 20/03/2026
10.0.6 17 11/03/2026
10.0.5 13 10/02/2026
10.0.4 8 28/01/2026
10.0.3 7 28/01/2026
10.0.2 20 12/12/2025
10.0.1 14 11/11/2025
9.2.4 11 06/11/2025
9.2.3 8 31/10/2025
9.2.2 7 20/10/2025
9.2.1 7 20/10/2025
9.2.0 9 15/10/2025
9.1.9 10 24/09/2025
9.1.8 20 06/09/2025
9.1.7 12 26/07/2025
9.1.6 12 15/07/2025
9.1.5 14 12/06/2025
9.1.4 46 19/05/2025
9.1.3 15 14/05/2025
9.1.2 24 09/04/2025
9.1.1 28 22/03/2025
9.1.0 15 19/03/2025
9.0.9 15 19/03/2025
9.0.8 14 19/03/2025
9.0.7 21 08/03/2025
9.0.6 15 05/03/2025
9.0.5 27 13/02/2025
9.0.4 15 12/02/2025
9.0.3 27 28/01/2025
9.0.2 19 23/01/2025
9.0.1 20 16/12/2024