【问题标题】:A localized scriptbundle solution本地化的 scriptbundle 解决方案
【发布时间】:2012-06-14 07:00:01
【问题描述】:

您好,我目前正在使用带有 System.Web.Optimization 的 asp.net MVC 4 rc。由于我的网站需要根据用户偏好进行本地化,因此我正在使用 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”,我希望提取以下文件(当然要缩小,如果可能的话还要缓存,直到脚本文件或当前的 ui 文化改变)。

  • “~/Scripts/jquery.globalize/globalize.js”
  • "~/Scripts/jquery.globalize/globalize-en-GB.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;
    }

}

谢谢

君士坦丁

【问题讨论】:

    标签: asp.net-mvc localization bundling-and-minification asp.net-optimization


    【解决方案1】:

    没错,bundle 只能在应用启动前配置。否则,在多服务器场景中,如果对 bundle 的请求被路由到提供页面的服务器之外的另一台服务器,则找不到对 bundle 资源的请求。

    这有意义吗?基本上,您的所有捆绑包都需要提前配置和定义,而不是根据每个请求动态注册。

    【讨论】:

    • 是的,这当然是真的。但看起来,当 js 或 css 文件更改服务器端时,捆绑包会被重新评估以保持最新(内部可能使用 FileSystemWatcher)。我看不出为什么不能覆盖此行为以考虑应用程序生命周期中的其他事件,例如 UI 文化的变化。
    • 是的,捆绑响应设置了缓存依赖项,以在捆绑中的文件更改时使缓存条目无效。我们已经在待办事项列表上开放了缓存行为以进行扩展,但我不确定我们什么时候能做到这一点。
    【解决方案2】:

    看看:https://stackoverflow.com/questions/18509506/search-and-replace-in-javascript-before-bundling

    我这样编码是为了满足我的需要:

    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));
        }
    }
    

    【讨论】:

    • 这个方案如何解决bundle创建后动态改变线程文化的问题?
    猜你喜欢
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多