Issues with localization in asp.net core site

I can’t get localization to work on my site. I’ve tried every config option, but it doesn’t return values from the resource files located in the Resources folder.

Config:
public static IServiceCollection AddAssetsSites(this IServiceCollection services, IConfiguration configuration, Action mvcOptions = default, params IAppFeatureBase features)
{
Identity ident = features.Exists(feat => feat.Type == AppFeatures.Identity) ? (Identity)features.Single(feat => feat.Type == AppFeatures.Identity) : new Identity(default, default);

	if (configuration.GetSection(AssetsStatics.ConfigSectionName).Exists())
	{
		IAssetsConfig cnf = new AssetsConfig(configuration);
		configuration.Bind(AssetsStatics.ConfigSectionName, cnf);

		services
			.AddOptions()
			.Configure<IConfiguration>(configuration)
			.AddTransient<IAssetsConfigAccessor, AssetsConfigAccessor>()
			.AddSingleton(cnf);
	}
	else
	{
		throw new ConfigSectionNotFoundException();
	}

	services
		.AddDbContext<AssetsDBContext>(opt => opt.UseSqlServer(AssetsStatics.ConnectionString))
		.AddTransient<IAssetsDBContext, AssetsDBContext>()
		.AddDbContext<AssetsIdentityDBContext>(opt => opt.UseSqlServer(AssetsStatics.ConnectionString))
		.AddTransient<IAssetsIdentityDBContext, AssetsIdentityDBContext>()
		.AddTransient<IAssetsDBContextAccessor, AssetsDBContextAccessor>()
		.AddHttpContextAccessor()
		.AddTransient<IActionContextAccessor, ActionContextAccessor>();

	services
		.AddTransient<IRepoFactory, RepoFactory>()
		.AddTransient<IServiceAccessFactory, ServiceAccessFactory>()
		.AddTransient<IQueryableExpressionFactory, QueryableExpressionFactory>()
		.AddTransient<IQueriesFactory, QueriesFactory>();

	services
		.AddIdentity<User, Role>(ident.IdentOptions)
		.AddUserManager<UserManager<User>>()
		.AddRoleManager<RoleManager<Role>>()
		.AddSignInManager<SignInManager<User>>()
		.AddEntityFrameworkStores<AssetsIdentityDBContext>()
		.AddDefaultTokenProviders().Services.ConfigureApplicationCookie(ident.CookieOptions)
		.AddTransient<IIdentityRepo, IdentityRepo>();

	if (features.Exists(feat => feat.Type == AppFeatures.SSL))
	{
		SSL ssl = (SSL)features.Single(feat => feat.Type == AppFeatures.SSL);

		services
			.AddHttpsRedirection(conf =>
			{
				conf.HttpsPort = ssl.Port;
			});
	}

	services
		.AddAssetsRepos()
		.AddTransient<ITagHelperRepo, TagHelperRepo>()
		.AddTransient<ISitesHelper, SitesHelper>()
		.Configure<CookiePolicyOptions>(opt =>
		{
			opt.CheckConsentNeeded = context => true;
			opt.MinimumSameSitePolicy = SameSiteMode.Unspecified;
		})
		.AddSession(opt =>
		{
			opt.IdleTimeout = TimeSpan.FromMinutes(180);
		});


	if (features.Exists(cnf => cnf.Type == AppFeatures.Localization))
	{
		Localization local = (Localization)features.Single(cnf => cnf.Type == AppFeatures.Localization);

		services
			.AddLocalization(opt => opt.ResourcesPath = local.ResourcePath)
			.AddControllersWithViews(mvcOptions)
			.AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
			.AddDataAnnotationsLocalization()
			.SetCompatibilityVersion(CoreStatics.DefaultCompatibilityVersion);

		services.Configure<RequestLocalizationOptions>(opt => {
			opt.DefaultRequestCulture = local.DefaultCulture;
			opt.SupportedCultures = local.SupportedCultures.ToList();
			opt.SupportedUICultures = local.SupportedCultures.ToList();
			opt.RequestCultureProviders = new List<IRequestCultureProvider> 
			{ 
				new QueryStringRequestCultureProvider(),
				new CookieRequestCultureProvider()
			};
		});
	}
	else
	{
		services
			.AddControllersWithViews(mvcOptions)
			.SetCompatibilityVersion(CoreStatics.DefaultCompatibilityVersion);
	}

	return services;
}

public static IApplicationBuilder UseAssetsSites(this IApplicationBuilder app, IConfiguration configuration, params IAppFeatureBase[] features)
{
	if (features.Exists(feat => feat.Type == AppFeatures.Debug))
	{
		Debug dg = (Debug)features.Single(feat => feat.Type == AppFeatures.Debug);

		if (dg.Environment.IsDevelopment() || dg.IgnoreEnvironment)
		{
			app.UseDeveloperExceptionPage();
		}
	}

	if (features.Exists(feat => feat.Type == AppFeatures.SSL))
	{
		app.UseHttpsRedirection();
	}

	app
		.UseRouting()
		.UseSession()
		.UseCookiePolicy(new CookiePolicyOptions
		{
			CheckConsentNeeded = context => true,
			MinimumSameSitePolicy = SameSiteMode.None
		});

	if (features.Exists(feat => feat.Type == AppFeatures.Localization))
	{
		Localization local = (Localization)features.Single(feat => feat.Type == AppFeatures.Localization);

		app.UseRequestLocalization(opt =>
		{
			opt.DefaultRequestCulture = local.DefaultCulture;
			opt.SupportedCultures = local.SupportedCultures.ToList();
			opt.SupportedUICultures = local.SupportedCultures.ToList();
		});
	}

	app.UseStaticFiles();

	if (features.Exists(feat => feat.Type == AppFeatures.DefaultRoute))
	{
		DefaultRoute route = (DefaultRoute)features.Single(feat => feat.Type == AppFeatures.DefaultRoute);

		app.UseEndpoints(opt =>
		{
			opt.MapControllerRoute("default", route.Route);
		});
	}
	else
	{
		app.UseEndpoints(opt => opt.MapDefaultControllerRoute());
	}

	return app;
}

_ViewImports.cshtml:
@using LC.Assets.Hyper;
@using Microsoft.AspNetCore.Mvc.Localization;

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers.Localization
@addTagHelper *, Creator.Components
@addTagHelper *, Assets.Core

@inject IViewLocalizer _localizer
@inject IHtmlLocalizer<SharedResources> _sharedLocalizer

Folder structure:
Root
-Resources

  • SharedResources.cs
  • SharedResources.en.resx
  • SharedResources.no.resx
  • Views.Home.Index.en.resx
  • Views.Home.Index.nb.resx
  • Views
    • Home
      *Index.cshtml

I’m really stuck on this one. Anyone got any ideas? Is it a config issue?

.NET Foundation Website | Blog | Projects | Code of Conduct