【问题标题】:Best practice for ASP.NET MVC resource filesASP.NET MVC 资源文件的最佳实践
【发布时间】:2010-12-24 22:13:05
【问题描述】:

以下资源文件的最佳用途是什么。

  1. 属性 → 资源(Phil 在 DataAnnotation 中使用此资源进行本地化)
  2. App_GlobalResources 文件夹
  3. App_LocalResources 文件夹

我也想知道 asp.net mvc 应用程序中的 (1) 和 (2) 有什么区别。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-2 localization resx


    【解决方案1】:

    属性 → 可以在视图之外看到资源,并且在编译应用程序时会生成强类型。​​

    App_* 在编译视图时由 ASP.NET 编译。它们仅在视图中可用。请参阅 this page 了解全局与本地。

    【讨论】:

      【解决方案2】:

      您应该避免使用App_GlobalResourcesApp_LocalResources。 就像 Craig 提到的那样,App_GlobalResources/App_LocalResources 存在问题,因为您无法在 ASP.NET 运行时之外访问它们。当您对应用程序进行单元测试时,这是一个很好的例子。

      K。斯科特艾伦不久前在博客上写过这个。他很好地解释了 ASP.NET MVC hereApp_GlobalResources 的问题。

      【讨论】:

        【解决方案3】:

        如果您采用推荐的解决方案 (1)(即 K. Scott Allen 的博客):

        对于那些尝试使用显式本地化表达式(也称为声明性资源绑定表达式)的人,例如<%$ Resources, MyResource:SomeString %>

        public class AppResourceProvider : IResourceProvider
        {
            private readonly string _ResourceClassName;
            ResourceManager _ResourceManager = null;
        
            public AppResourceProvider(string className)
            {
                _ResourceClassName = className;
            }
        
            public object GetObject(string resourceKey, System.Globalization.CultureInfo culture)
            {
                EnsureResourceManager();
                if (culture == null)
                {
                    culture = CultureInfo.CurrentUICulture;
                }
                return _ResourceManager.GetObject(resourceKey, culture);
            }
        
            public System.Resources.IResourceReader ResourceReader
            {
                get
                {
                    // Not needed for global resources
                    throw new NotSupportedException();
                }
            }
        
            private void EnsureResourceManager()
            {
                var assembly = typeof(Resources.ResourceInAppToGetAssembly).Assembly;
                String resourceFullName = String.Format("{0}.Resources.{1}", assembly.GetName().Name, _ResourceClassName);
                _ResourceManager = new global::System.Resources.ResourceManager(resourceFullName, assembly);
                _ResourceManager.IgnoreCase = true;
            }
        }
        
        public class AppResourceProviderFactory : ResourceProviderFactory
        {
            // Thank you, .NET, for providing no way to override global resource providing w/o also overriding local resource providing
            private static Type ResXProviderType = typeof(ResourceProviderFactory).Assembly.GetType("System.Web.Compilation.ResXResourceProviderFactory");
            ResourceProviderFactory _DefaultFactory;
        
            public AppResourceProviderFactory()
            {
                _DefaultFactory = (ResourceProviderFactory)Activator.CreateInstance(ResXProviderType);
            }
        
            public override IResourceProvider CreateGlobalResourceProvider(string classKey)
            {
                return new AppResourceProvider(classKey);
            }
        
            public override IResourceProvider CreateLocalResourceProvider(string virtualPath)
            {
                return _DefaultFactory.CreateLocalResourceProvider(virtualPath);
            }
        }
        

        然后,将其添加到您的 web.config:

            <globalization requestEncoding="utf-8" responseEncoding="utf-8" fileEncoding="utf-8" culture="en-US" uiCulture="en"
                           resourceProviderFactoryType="Vendalism.ResourceProvider.AppResourceProviderFactory" />
        

        【讨论】:

        • 什么是Resources.ResourceInAppToGetAssembly?它没有编译,我找不到任何对它的引用,但在这个例子中?它是您正在使用的实际资源类的化名吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多