Локализованное решение сценария

Привет. Я использую asp.net MVC 4 rc с System.Web.Optimization. Поскольку мой сайт должен быть локализован в соответствии с предпочтением пользователя, я работаю с плагином jquery.globalize.

Я бы очень хотел подклассифицировать класс ScriptBundle и определить, какие файлы нужно связывать в соответствии с System.Threading.Thread.CurrentThread.CurrentUICulture. Это будет выглядеть так:

bundles.Add(new LocalizedScriptBundle("~/bundles/jqueryglobal")
                             .Include("~/Scripts/jquery.globalize/globalize.js")
                             .Include("~/Scripts/jquery.globalize/cultures/globalize.culture.{0}.js", 
                                       () => new object[] { Thread.CurrentThread.CurrentUICulture })
                    ));

Например, если культура ui является "en-GB", я бы хотел, чтобы следующие файлы были подхвачены (конечно, и, если возможно, кэшированы, а до тех пор, пока не будет изменен файл script или культура currentui).

  • "~/Scripts/jquery.globalize/globalize.js"
  • "~/Scripts/jquery.globalize/globalize-en-GB.js" < - если этот файл не существует в файловой системе sever, поэтому возвратитесь к globalize-en.js.

Я попытался перегрузить метод Include с чем-то вроде следующего, но это не будет работать, потому что оно не оценивается по запросу, а при запуске приложения.

public class LocalizedScriptBundle : ScriptBundle
{
    public LocalizedScriptBundle(string virtualPath)
        : base(virtualPath) { 
    }

    public Bundle Include(string virtualPathMask, Func<object[]> getargs) {
        string virtualPath = string.Format(virtualPathMask, getargs());
        this.Include(virtualPath);
        return this;
    }

}

Спасибо

Константинос

Ответ 1

Правильно, пучки должны быть настроены только для предварительного запуска приложения. В противном случае в сценарии с несколькими серверами, если запрос для пакета перенаправляется на другой сервер, отличный от того, который обслуживал страницу, запрос на ресурс узла не будет найден.

Это имеет смысл? В принципе, все ваши пакеты необходимо настраивать и определять заранее, а не динамически регистрировать на основе запроса.

Ответ 2

посмотрите: fooobar.com/info/480641/...

Я закодировал этот путь для своих нужд:

public class MultiLanguageBundler : IBundleTransform
{
    public void Process(BundleContext context, BundleResponse bundle)
    {
        var content = new StringBuilder();
        var uicult = Thread.CurrentThread.CurrentUICulture.ToString();

        var localizedstrings = GetFileFullPath(uicult);
        if (!File.Exists(localizedstrings))
        {
            localizedstrings = GetFileFullPath(string.Empty);
        }

        using (var fs = new FileStream(localizedstrings, FileMode.Open, FileAccess.Read))
        {
            var m_streamReader = new StreamReader(fs);
            var str = m_streamReader.ReadToEnd();

            content.Append(str);
            content.AppendLine();
        }

        foreach (var file in bundle.Files)
        {
            var f = file.VirtualFile.Name ?? "";

            if (!f.Contains("localizedstrings"))
            {
                using (var reader = new StreamReader(VirtualPathProvider.OpenFile(file.VirtualFile.VirtualPath)))
                {
                    content.Append(reader.ReadToEnd());
                    content.AppendLine();
                }
            }
        }

        bundle.ContentType = "text/javascript";
        bundle.Content = content.ToString();
    }

    private string GetFileFullPath(string uicult)
    {
        if (uicult.StartsWith("en"))
            uicult = string.Empty;
        else if (!string.IsNullOrEmpty(uicult))
            uicult = ("." + uicult);

        return Kit.ToAbsolutePath(string.Format("~/Scripts/locale/localizedstrings{0}.js", uicult));
    }
}