zoukankan      html  css  js  c++  java
  • 自定义ResourceProviderFactory、IResourceProvider实现ASP.NET、ASP.NET MVC多语言支持

    ASP.NET的默认资源分为Global、Local(ASP.NET Folder的App_GlobalResources、APP_LocalResources)。App_GlobalResources为全局共享资源、App_LocalResources根据虚拟路径对应到页面。如何获取这两类资源需要实现System.Web.Compilation.ResourceProviderFactory的两个函数:CreateGlobalResourceProvider、CreateLocalResourceProvider,两者都返回一个System.Web.Compilation.IResourceProvider的实现。本文主要描述如何实现加载外部资源,并不考虑针对virtualPath的映射。下面是一个ResourceProviderFactory的实现:

    /// <summary>
    /// 外部资源提供器工厂
    /// </summary>
    public sealed class ExternalResourceProviderFactory : ResourceProviderFactory
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ExternalResourceProviderFactory() { }
    
        /// <summary>
        /// 获取全局资源提供器
        /// </summary>
        /// <param name="classKey">类键值</param>
        /// <returns>资源提供器</returns>
        public override IResourceProvider CreateGlobalResourceProvider(String classKey)
        {
            return new GlobalExternalResourceProvider(classKey);
        }
    
        /// <summary>
        /// 获取本地资源提供器
        /// </summary>
        /// <param name="virtualPath">虚拟路径</param>
        /// <returns>资源提供器</returns>
        public override IResourceProvider CreateLocalResourceProvider(String virtualPath)
        {
            throw new NotSupportedException();
        }
    }

    ASP.NET默认的ResourceExpressionBuilder支持<%$ Resources:[ClassKey], [ResourceKey]%>格式语法,通过自定义ClassKey的规则加载一个外部程序集的资源类型:[AssemblyName]|[ResourceTypeName]。比如:<%$ Resources:MultiLangDemo1.Resources|Strings, Button_Click%>,根据这个规则编写一个支持规则的IResourceProvider实现:

    /// <summary>
    /// 全局外部资源提供器
    /// </summary>
    public sealed class GlobalExternalResourceProvider : IResourceProvider
    {
        /// <summary>
        /// 分隔符-类键值
        /// </summary>
        private const Char SEPARATOR_CLASSKEY = '|';
    
        private Lazy<ResourceManager> _lazyResourceMangaer;
    
        private String _assemblyName;
        private String _typeName;
    
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="classKey">类键值</param>
        public GlobalExternalResourceProvider(String classKey)
        {
            String[] strArray = classKey.Split(SEPARATOR_CLASSKEY);
    
            if (strArray.Length == 0)
                throw new ArgumentException("格式不正确");
    
            _assemblyName = strArray[0];
            _typeName = strArray[1];
            _lazyResourceMangaer = new Lazy<ResourceManager>(CreateResourceManager);
        }
    
        /// <summary>
        /// 资源管理器
        /// </summary>
        private ResourceManager ResourceManager
        {
            get
            {
                return _lazyResourceMangaer.Value;
            }
        }
    
        /// <summary>
        /// 创建资源管理器
        /// </summary>
        /// <returns>资源管理器</returns>
        private ResourceManager CreateResourceManager()
        {
            Assembly assembly = Assembly.Load(_assemblyName);
    
            return new ResourceManager(String.Format(CultureInfo.InvariantCulture, "{0}.{1}", _assemblyName, _typeName), assembly);
        }
    
        #region IResourceProvider Members
    
        /// <summary>
        /// 获取资源对象
        /// </summary>
        /// <param name="resourceKey">资源键</param>
        /// <param name="culture">文化信息</param>
        /// <returns>资源对象</returns>
        public Object GetObject(String resourceKey, CultureInfo culture)
        {
            if (culture == null)
                culture = CultureInfo.CurrentUICulture;
    
            return this.ResourceManager.GetObject(resourceKey, culture);
        }
    
        /// <summary>
        /// 资源读取器
        /// </summary>
        public IResourceReader ResourceReader
        {
            get
            {
                throw new NotImplementedException();
            }
        }
    
        #endregion
    }

    如果想要自定义表达式的语法,可以继承System.Web.Compilation.ExpressionBuilder。在Web.config中配置自定义的ResourceProviderFactory:

    <configuration>
      <system.web>
        <compilation debug="true"
                     targetFramework="4.0" />
        <globalization uiCulture="auto"
                       culture="auto"
                       resourceProviderFactoryType="CustomResourceProviders.ExternalResourceProviderFactory, CustomResourceProviders" />
      </system.web>
    </configuration>

    在.aspx页面尝试访问某个外部程序集资源键值:

    <asp:Button ID="btnClick" runat="server" Text="<%$ Resources:MultiLangDemo1.Resources|Strings, Button_Click %>"
        OnClick="btnClick_Click" />

    ASP.NET MVC中继续使用这种方式,只需添加System.Web.Mvc.HtmlHelper<T>对应的扩展函数,访问HttpContextBase的GetGlobalResourceObject函数就可实现:

    /// <summary>
    /// HtmlHelper扩展函数
    /// </summary>
    public static class HtmlHelperExtension
    {
        /// <summary>
        /// 获取全局资源对象
        /// </summary>
        /// <param name="html">Html辅助类</param>
        /// <param name="classKey">类键值</param>
        /// <param name="resourceKey">资源键</param>
        /// <returns>资源对象</returns>
        public static Object GetGlobalResourceObject<T>(this HtmlHelper<T> html, String classKey, String resourceKey)
        {
            return GetGlobalResourceObject(html, classKey, resourceKey);
        }
    
        /// <summary>
        /// 获取全局资源对象
        /// </summary>
        /// <param name="html">Html辅助类</param>
        /// <param name="classKey">类键值</param>
        /// <param name="resourceKey">资源键</param>
        /// <param name="culture">文化信息</param>
        /// <returns>资源对象</returns>
        public static Object GetGlobalResourceObject<T>(this HtmlHelper<T> html, String classKey, String resourceKey, CultureInfo culture)
        {
            if (culture == null)
                culture = CultureInfo.CurrentUICulture;
    
            return html.ViewContext.HttpContext.GetGlobalResourceObject(classKey, resourceKey, culture);
        }
    
        /// <summary>
        /// 获取全局资源字符串
        /// </summary>
        /// <param name="html">Html辅助类</param>
        /// <param name="classKey">类键值</param>
        /// <param name="resourceKey">资源键</param>
        /// <returns>资源对象</returns>
        public static String GetGlobalResourceAsString<T>(this HtmlHelper<T> html, String classKey, String resourceKey)
        {
            return GetGlobalResourceAsString(html, classKey, resourceKey, null);
        }
    
        /// <summary>
        /// 获取全局资源字符串
        /// </summary>
        /// <param name="html">Html辅助类</param>
        /// <param name="classKey">类键值</param>
        /// <param name="resourceKey">资源键</param>
        /// <param name="culture">文化信息</param>
        /// <returns>资源对象</returns>
        public static String GetGlobalResourceAsString<T>(this HtmlHelper<T> html, String classKey, String resourceKey, CultureInfo culture)
        {
            return GetGlobalResourceObject(html, classKey, resourceKey, culture) as String;
        }
    }

    在view中使用它:

    <input type="button" value="@Html.GetGlobalResourceAsString("MultiLangDemo1.Resources|Strings", "Button_Click")" />
  • 相关阅读:
    WPF 如何创建自己的WPF自定义控件库
    浅谈WPF的VisualBrush
    从Oracle数据库中查询前几个月数据时需要注意的一些问题
    WPF当属性值改变时利用PropertyChanged事件来加载动画
    java array to list
    nGrinder 简易使用教程
    页面json 格式化+颜色高亮
    通过maven test 报org.apache.ibatis.binding.BindingException: Invalid bound statement
    jenkins 多选框
    jstack jstat 简易使用教程
  • 原文地址:https://www.cnblogs.com/junchu25/p/2769006.html
Copyright © 2011-2022 走看看