从页面加载以编程方式本地化aspx页面

时间:2012-02-26 23:59:42

标签: c# asp.net performance localization

我正在开发一个新项目,我正在努力坚持一些自定义规则,看看我是否能够以更好的方式解决旧问题,但我很少有疑问,我会喜欢来自经验丰富的开发人员的一些反馈

我正在使用bootstrap和jQuery开发UI层,aspx基本上是生成静态html并执行大量的ajax。

一个老问题是本地化,几种不同的语言。我正在做的是将页面的本地化片段包装在自定义标签中,如下所示:

<localization culture="en" runat="server">
    <h3>Add everything...</h3>
    <p><i>Remember you can add also <a href="">by email</a> and <a href="">by gtalk</a>.</i></p>
</localization>
<localization culture="it" runat="server">
    <h3>Aggiungi tutto...</h3>
    <p><i>Ricorda che puoi farlo anche <a href="">via email</a> e <a href="">via gtalk</a>.</i></p>
</localization>

然后在我的page_load中调用递归函数:

  protected void Page_Load(object sender, EventArgs e)
  {
     Localization(Page);
  }

以下内容:

  protected void Localization(Control parent)
  {
     foreach (Control c in parent.Controls)
     {
        if (c.GetType() == typeof(HtmlGenericControl))
        {
           HtmlGenericControl hgc = (HtmlGenericControl)c;
           if( hgc.TagName == "localization")
           {
              if (hgc.Attributes["culture"] != null && hgc.Attributes["culture"] != lu.ui_culture)
              {
                 c.Visible = false;
              }
           }
        }

        Localization(c);
     }
  }

我可以看到这种方法有一些缺点:我不能将翻译放在单独的xml文件中,而是使用递归函数处理html。

但与此同时我喜欢它,因为它可以很容易地翻译带有大量html标记的片段,而且我也可以将所有内容放在一个地方。

过去我使用不同的方法,使用xslt + xml渲染html,但也是一场噩梦,即使你成功地没有内联javascript的纯粹主义,并且没有内联CSS在视觉上很复杂,无法管理xml和html在一个文件中。


所以我的问题是:

  1. 是一个愚蠢的解决方案吗?
  2. 表现明智太糟糕了?
  3. 我怎样才能以非技术人员编辑翻译文件的方式管理最具活力的内容?

3 个答案:

答案 0 :(得分:1)

这不是一个愚蠢的解决方案,它看起来比做一些可怕的xslt mangling简单得多:)

性能方面它会没问题,但最终这一切都取决于有多少请求命中你的服务器以及它是否可以跟上负载。如果你期望轻载(少数用户),你会没事的。

另一种解决方案是将所有翻译存储在数据库中,编写一个漂亮的前端,以便翻译人员可以维护它们,并在每个页面请求时获取该特定页面的所有翻译。这个表格看起来像:

tblControlTranslation(PageName(nvarchar),ControlName(nvarchar),Translation(nvarchar))。

默认情况下,每个控件都有英文(所以你知道是什么),然后代码将循环遍历每个控件并将翻译后的文本放入。

答案 1 :(得分:0)

这似乎并不适合ASP.NET的本地化模型。为什么需要在ASPX中定义所有本地化?您是否考虑过使用标准的ASP.NET本地化设施?请考虑审核http://www.codeproject.com/Articles/38907/ASP-NET-Localization-Quick-Reference

您可以创建一个从XML读取数据的自定义资源提供程序。这样做非常简单 - 我们只是编写了一个自定义资源提供程序,它从数据库中读取数据 - 我们需要所有最终用户更新一些值 - 因此选择DB。非开发人员更改XML文件相对容易 - 或者您可以轻松地在其上创建简单的UI。这也可以让您更轻松地管理CSS名称的更改。

您正在采用的当前方法会使您的ASPX与所有语言的翻译混乱,并会在一段时间内增加您的可维护性问题。这种方法也会导致违反分离关注原则 - 在某种程度上 - 因为您的网页会因正常工作而负担过重,并且有责任进行本地化。

有关详情,请参阅Extending the ASP.NET 2.0 Resource-Provider Model上优秀且详细的MSDN文章。基本上,您需要实现以下类/接口并通过Web.config链接它们。然后,您可以拥有特定于页面的XML文件或全局XML文件,您可以从中读取本地化的值。如果需要,这也将打开在页面之间共享本地化值的大门。

ResourceProviderFactory:

namespace System.Web.Compilation
{
    public abstract class ResourceProviderFactory
    {
        public abstract IResourceProvider CreateGlobalResourceProvider(string classKey);
        public abstract IResourceProvider CreateLocalResourceProvider(string virtualPath);
    }
}

IResourceProvider:

namespace System.Web.Compilation
{
    public interface IResourceProvider
    {
        IResourceReader ResourceReader { get; }

        object GetObject(string resourceKey, CultureInfo culture);
    }
}

Web.config更改:

<system.web>
    <globalization resourceProviderFactoryType="MyCompany.Localization.CustomResourceProviderFactory" />
</system.web>

XML文件的XML结构示例 - 适用于每个页面或完整应用程序:

<LocalizedValues>
    <Value Key="FirstTextBlock">
        <LocalizedFor Culture="en-us">
            ...
        </LocalizedFor>
        <LocalizedFor Culture="it">
            ...
        </LocalizedFor>
    </Value>
</LocalizedValues>

答案 2 :(得分:0)

我运行了一些简单的测试,使用上面的递归函数,并根据所选语言执行一些xslt替换html中的文本。 使用上面的递归函数工具0,001349秒,使用xslt它花了0,006989。 然而,最后我选择使用xslt,然后根据所选语言缓存结果,以提高性能并能够在单个xml文件中维护所有翻译。