Спутниковая сборка, язык ASP.NET не меняется

Я конвертирую проект для использования спутниковой сборки. Я создал новую библиотеку классов (названную "Ресурсы"). Все ресурсы по умолчанию находятся на корневом уровне *.resx, Тогда есть папка для каждой культуры.

"en /" с *.en.resx

en-GB/ с *.en-GB.resx

Я изменил файлы.resx Access Modifier в "Public" и изменил эти настройки.

BuildAction: EmbeddedResource
CopyToOutputDirectory: CopyAlways

Я убедился .resx дизайнеры *.Designer.cs используйте пространство имен "Ресурсы".

Я добавил библиотеку классов в приложение ASP.NET MVC и в global.asax.cs У меня культура устанавливается по мере необходимости.

System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");

Я пытался добавить al.exe а также Resgen.exe команды для события после сборки в библиотеке классов Resources.

"C: \ Program Files \ Microsoft SDKs \ Windows \ v7.1 \ Bin \ Resgen.exe" ru-GB/MyResourceFile.en-GB.resx "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\al.exe" /t:lib /embed:en-GB/MyResourceFile.en-GB.resources /culture:en-gb /out:Resources.resources.dll

Заглядывая в приложения MVC bin/ В папке есть папки для каждого языка с 3 файлами:

MyResources.en-GB.Designer.cs, MyResources.en-GB.resx, Resources.resources.dll

Корневой уровень имеет только Resources.dll а также Resources.resources.dll но язык по умолчанию работает нормально. Второй *.resources.dll связано с событием после сборки.

Когда я меняю CurrentUICulture, это не меняет язык интерфейса. Прежде чем перемещать ресурсы из App_GlobalResources/ для внешней сборки все работало нормально (пример Razor).

@Resources.MyResources.StringIdentifier 

Глядя на ресурс .dlls с помощью.NET Reflector это различия.

Satellite Resources: (Project: Resources)
Resources.en_GB.MyResources.en-GB.resources 
App_GlobalResources: (Project MVCApp)
Namespace.MVCApp.App_GlobalResources.MyResources.en-GB.resources

Редактировать:

После настройки CurrentCulture и UICulture в global.asax.csЯ проверил вручную ResourceManager который фактически работал и извлекал строки на ожидаемом языке.

            System.Resources.ResourceManager gStrings =
                new System.Resources.ResourceManager("Resources.MyResources", System.Reflection.Assembly.Load("Resources")); // Resources=Project Name
            string test = gStrings.GetString("TestString"); // WORKS IN GLOBAL.ASAX.CS!!!

Я попробовал тот же тест в контроллере MVC, но он не работает. Таким образом, единственное место, где можно получить ResourceManager - это Global.asax.cs.

Как ни странно, тот же тест на уровне пользовательского интерфейса в бритве вернул бы только текст культуры по умолчанию! CultureInfo верен, но ResourceManager возвращает язык по умолчанию только в пользовательском интерфейсе ASP.NET MVC Razor. (Это строго для тестирования)

    @{  
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentUICulture;
        System.Resources.ResourceManager gStrings =
            new System.Resources.ResourceManager("Resources.MyResource", System.Reflection.Assembly.Load("Resources"));
        string s = gStrings.GetString("Test");    // DOESN'T WORK IN UI
    }

Версия TLDR:

Преобразование из ресурсов (.resx) из App_GlobalResources в спутниковые сборки.

Вопрос под рукой.

Я могу вручную вызвать ResourceManager для спутниковой сборки, используя язык CurrentUICulture в global.asax и он работает, как и ожидалось, однако тот же тест не проходит со стороны пользовательского интерфейса и не проходит в контроллере MVC.

Язык по умолчанию работает нормально, так почему же пользовательский интерфейс не переключает языки?

1 ответ

Если недавно создали проект, в котором интернационализация работает более или менее правильно, как вы описали.

https://github.com/Jacco/Perpetuality

Я переключаю язык для HTTP-запроса в OnAuthorize в контроллере, который я использую в качестве базы:

using Perpetuality.Data;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;


namespace Perpetuality.Controllers
{
    public partial class BaseController : Controller
    {
        private CultureInfo GetCultureInfo(AuthorizationContext filterContext)
        {
            switch ((string)filterContext.RouteData.Values["language"])
            {
                case "nl":
                    return CultureInfo.CreateSpecificCulture("nl-NL");
                case "en":
                    return CultureInfo.CreateSpecificCulture("en-US");
                case "pt":
                    return CultureInfo.CreateSpecificCulture("pt-PT");
                case "de":
                    return CultureInfo.CreateSpecificCulture("de-DE");
                case "es":
                    return CultureInfo.CreateSpecificCulture("es-ES");
                case "fr":
                    return CultureInfo.CreateSpecificCulture("fr-FR");
                case "it":
                    return CultureInfo.CreateSpecificCulture("it-IT");
                case "jp":
                    return CultureInfo.CreateSpecificCulture("ja-JP");
                default:
                    return CultureInfo.CreateSpecificCulture("en-US");
            }
        }

        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            Thread.CurrentThread.CurrentCulture = GetCultureInfo(filterContext);
            Thread.CurrentThread.CurrentUICulture = GetCultureInfo(filterContext);

            base.OnAuthorization(filterContext);
        }
    }
}

В моем проекте файлы RESX указаны иначе, чем в вашем:

BuildAction: EmbeddedResource
CopyToOutputDirectory: DoNotCopy

В моих соперниках я получаю доступ к таким строкам:

@Resources.Home.Index.FacebookButtonCaption

Я ничего не установил после публикации или предварительной сборки.

В моем проекте язык всегда на URL. Таким образом, пользователь мог переключать язык, если изначально не был выбран соответствующий язык.

Другие вопросы по тегам