Reputation: 710
I have a project in which I use resource files to store some text, I am also trying to use StringLocalizer<> to obtain a desired message from resource files. I have already configured localization settings in Startup class as shown below:
internal static class LocalizationConfiguration
{
private const string ResourcesPath = "Resources";
private const string DefaultCulture = "en-US";
internal static IServiceCollection ConfigureLocalizationSettings(this IServiceCollection services) =>
services
.AddLocalization(options =>
options.ResourcesPath = ResourcesPath);
internal static IApplicationBuilder UseRequestLocalizationMiddleware(this IApplicationBuilder builder) =>
builder
.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture(DefaultCulture),
SupportedCultures = new List<CultureInfo>
{
new CultureInfo(DefaultCulture)
}
});
}
My solution consists of few projects. I need to use StringLocalizer in project which contains my business logic - xxx.Handlers. I have also created a project called xxx.Resources for storing resources which contains two directories:
Here's my UserMessages class (it's empty, dummy class, following to https://learn.microsoft.com/pl-pl/aspnet/core/fundamentals/localization?view=aspnetcore-3.1):
public class UserMessages
{
}
I injected StringLocalizer to my command handler and then used it like below (UserConstants.UserNotFoundMessageKey is ok):
var userEntity = await _userRepository.GetUserByIdAsync(command.UserId);
if (userEntity is null)
{
var message = _stringLocalizer[UserConstants.UserNotFoundMessageKey];
var statusCode = (int) HttpStatusCode.NotFound;
throw new CommandException(message, statusCode);
}
The problem is, my messages are not being localized in a proper way, and the expression "_stringLocalizer[UserConstants.UserNotFoundMessageKey]" actually returns value of UserNotFoundMessageKey instead of message located in resource file. What am I doing wrong?? How to localize those messages correctly?
Upvotes: 2
Views: 3355
Reputation: 36715
Here is a whole working solution about how to create a shared resource in a separate project:
In ProjectA(It is SharedResource3_1
in my solution):
1.Create Shared
folder with UserMessages
class and Create Resources
folder with Shared.UserMessages.en-US.resx
file(Not sure why you create Shared.UserMessages.en-US.Designer.cs
,but it seems to be not useful):
UserMessages.cs
:
namespace SharedResource3_1.Shared
{
public class UserMessages
{
}
}
Shared.UserMessages.en-US.resx
:
In ProjectB(It is MvcCore3_1
in my solution):
1.Add Project Reference to ProjectA:
Right-click
the ProjectB Dependencies
and choose Add Project Reference
then choose the ProjectA:
Then you could get the reference like below:
2.Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
//add this...
LocalizationConfiguration.ConfigureLocalizationSettings(services);
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//add this...
LocalizationConfiguration.UseRequestLocalizationMiddleware(app);
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
internal static class LocalizationConfiguration
{
private const string ResourcesPath = "Resources";
private const string DefaultCulture = "en-US";
internal static IServiceCollection ConfigureLocalizationSettings(this IServiceCollection services) =>
services
.AddLocalization(options =>
options.ResourcesPath = ResourcesPath);
internal static IApplicationBuilder UseRequestLocalizationMiddleware(this IApplicationBuilder builder) =>
builder
.UseRequestLocalization(new RequestLocalizationOptions
{
DefaultRequestCulture = new RequestCulture(DefaultCulture),
SupportedCultures = new List<CultureInfo>
{
new CultureInfo(DefaultCulture)
}
});
}
3.HomeController:
using SharedResource3_1.Shared; //add the reference for the UserMessages in ProjectA
public class HomeController : Controller
{
private readonly IStringLocalizer<UserMessages> _stringLocalizer;
public HomeController(IStringLocalizer<UserMessages> stringLocalizer)
{
_stringLocalizer = stringLocalizer;
}
public IActionResult Index()
{
ViewBag.data = _stringLocalizer["cześć"]; //the key name should be the Name in your resx file...
return View();
}
}
Result:
Upvotes: 5