0

In my app, I have 2 projects, MyApp.Web and MyApp.ClassLibrary project. In the ClassLibrary project, I have AccountType enum that I'm trying to localize. I'm able to achieve it using standard SharedResources setup, but I would like to use separate resources files for the ClassLibrary

The error I'm getting is:

InvalidOperationException: Cannot retrieve property 'Name' because localization failed. Type 'MyApp.ClassLibrary.AccountResources' is not public or does not contain a public static string property with the name 'Active'.

The AccountType enum:

namespace MyApp.ClassLibrary.Accounts;

public enum AccountType
{
    [Display(Name = "Active", ResourceType = typeof(AccountResources))]
    Active,
    [Display(Name = "Disabled", ResourceType = typeof(AccountResources))]
    Disabled,
    [Display(Name = "Demo", ResourceType = typeof(AccountResources))]
    Demo
}

I have created a dummy class at the root of the ClassLibrary project:


namespace MyApp.ClassLibrary;
public class AccountResources
{
}

I have created Resources folder inside the Web project, and put the Accounts.AccountResources.uz-Latn-UZ.resx file in there.

In the Program.cs, my configuration is as follows:

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


builder.Services.AddControllersWithViews().AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix).AddDataAnnotationsLocalization(options => {
        options.DataAnnotationLocalizerProvider = (type, factory) =>
            factory.Create(typeof(SharedResources));
    });

Note: You can notice that I'm using SharedResources here and they do work for the enums in the ClassLibrary. But I would prefer to have separate resource files for the ClassLibrary project, including localization for the enums.

The access modifier for the Accounts.AccountResources.uz-Latn-UZ.resx file is set to 'No code generation', the same as in SharedResources.uz-Latn-UZ.resx (which works).

I tried to move the Accounts.AccountResources.uz-Latn-UZ.resx in the Resources folder in the ClassLibrary, but I'm getting the same error.

Is this configuration wrong? Is there a proper way to achieve the required setup without using SharedResources?

Thank you!

Donny
  • 1
  • Does this help https://stackoverflow.com/questions/42044458/asp-net-core-localized-resource-in-separate-assembly – Qiang Fu Apr 28 '23 at 10:01
  • @QiangFu, it works fine for my other resources that use IStringLocalizer, IVIewLocalizer, etc. But for localizing enums, I'm using DataAnnodations like this: `[Display(Name = "Active", ResourceType = typeof(AccountResources))]`. For DataAnnotations, it's not working. – Donny Apr 28 '23 at 15:37

1 Answers1

0

You can try this code. Create a AccountResources.resx file at root, no need for register service. Set the Access Modifier as 'public'.
enter image description here enter image description here

Product.cs

    public class Product
    {
        public AccountType AccountType1 { get; set; }
    }
    public enum AccountType
    {
        [Display(Name = "Active", ResourceType = typeof(AccountResources))]
        Active,
        [Display(Name = "Disabled", ResourceType = typeof(AccountResources))]
        Disabled,
        [Display(Name = "Demo", ResourceType = typeof(AccountResources))]
        Demo
    }

Controller

        public IActionResult Index()
        {
            var result = new Product() { accountType = AccountType.Demo };
            
            return View(result);
        }

Index.cshtml

@model WebApplication9.Models.Product
@Html.DisplayTextFor(m=>m.accountType)

Output
enter image description here

Qiang Fu
  • 1,401
  • 1
  • 2
  • 8
  • It works if I make it as you suggest. But to reproduce my problem, try to do the following: 1. Move `AccountResources.resx` and `Product` and `AccountType` to a Class library project. – Donny May 05 '23 at 01:43
  • 2. Try to use language specific resource file, like `AccountResources.fr.resx`. When I add language specific file, only the .resx XML file itself is generated and there is no backround C# class. So I can't see the resource with `typeof()`. Now I add a dummy `AccountResources.cs`. It gets linked to to the `fr.resx` file automatically. But when I run this setup, I get this error: `InvalidOperationException: Cannot retrieve property 'Name' because localization failed. Type 'MyApp.Domain.AccountResources' is not public or does not contain a public static string property with the name 'Active'.` – Donny May 05 '23 at 02:02