从页面加载以编程方式本地化aspx页面
本文关键字:方式 本地化 aspx 页面 编程 加载 | 更新日期: 2023-09-27 18:25:48
我正在进行一个新项目,我正在努力遵守一些自定义规则,看看我是否能以更好的方式解决旧问题,但我没有什么疑问,我希望更有经验的开发人员能给我一些的反馈。
我正在使用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在视觉上也很复杂。
所以我的问题是:
- 这是一个愚蠢的解决方案吗
- 性能方面是否太差
- 我怎样才能以非技术人员可以编辑翻译文件的方式管理最动态的内容
这不是一个愚蠢的解决方案,它看起来比做一些可怕的xslt篡改要简单得多:)
就性能而言,这是可以的,但最终这一切都取决于有多少请求到达你的服务器,以及它是否能跟上负载。如果你希望负载较轻(少数用户),你会没事的。
另一种解决方案是将所有翻译存储在DB中,编写一个漂亮的前端,以便翻译人员可以维护它们,并在每个页面请求时获取该特定页面的所有翻译。这个表格看起来像:
tblControlTranslation(PageName(nvarchar)、ControlName(nvarchar)、Translation。
默认情况下,每个控件中都有英文(这样你就知道是什么了),然后代码会在每个控件中循环,并将翻译后的文本放入。
这似乎并不真正"适合"ASP.NET的本地化模型。为什么需要在ASPX中定义所有本地化?您是否考虑过使用标准的ASP.NET本地化功能?考虑审查http://www.codeproject.com/Articles/38907/ASP-NET-Localization-Quick-Reference
您可以创建一个从XML中读取数据的自定义资源提供程序。做到这一点非常简单——我们刚刚编写了一个从数据库读取数据的自定义资源提供程序——我们需要所有最终用户更新一些值——所以选择数据库。对于非开发人员来说,更改XML文件相对容易,或者您可以很容易地在上面创建一个简单的UI。这也将允许您更容易地管理CSS名称的更改。
你目前采用的方法会让你的ASPX充斥着所有语言的翻译,并在一段时间内增加你的可维护性问题。这种方法也会在一定程度上违反关注点分离原则,因为您的页面将超负荷地进行正常工作,并有责任进行本地化。
有关更多详细信息,您可以参阅MSDN上关于扩展ASP.NET 2.0资源提供程序模型的精彩而详细的文章。基本上,您需要实现以下类/接口,并通过Web.config将它们链接进来。然后,您可以拥有特定于页面的或全局的XML文件,从中可以读取本地化值。如果需要,这也将打开跨页面共享本地化值的大门。
资源提供者工厂:
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>
我运行了一些简单的测试,使用上面的递归函数,并根据所选的语言执行一些xslt来替换html中的文本。使用上面的递归函数工具0001349秒,使用xslt花费了0006989秒。然而,最后我选择使用xslt,然后缓存因所选语言而异的结果,以提高性能并能够在单个xml文件中维护所有翻译。