我要实现这样一个功能,就是
按
一个按键在两种语言(比如中文和英文)之间切换。
注:我用的是ASP.NET Beta 2。 参考文章列在最后。
参考第一篇文章, "Implicit Localization Expressions"一 节 。一个页面 ( Page ) 的本地化内容是在 FrameworkInitlize()中创建所有的控件时决定的。比如
button1.Text = ((string)
base.GetLocalResourceObject("LinkButtonResource1.Text"));
所以要在 FrameworkInitlize()之前设置好你所需要的页面的文化(Culture).
第二篇文章 " Page Lifecycle "一 节 列出了页面 的生命周期(Lifecycle )涉及的方法 。下面列出了从 页面 的构造函数( Constructor )开始与我的问题相关的一些方法。
Constructor
Construct
TestDeviceFilter
AddParsedSubObject
DeterminePostBackMode
OnPreInit
LoadPersonalizationData
InitializeThemes
OnInit
在第三篇文章"The Page Lifecycle"的开头写道:
Once the HTTP page handler class is fully identified, the ASP.NET run time calls the handler's ProcessRequest method to process the request. ... (it) begins by calling the method FrameworkInitialize, which builds the controls tree for the page. The method is a protected and virtual member of the TemplateControl class - the class from which Page itself derives. Any dynamically generated handler for an .aspx resource overrides FrameworkInitialize. In this method, the whole control tree for the page is built.
Next, ProcessRequest makes the page transit various phases: initialization, loading of view state information and postback data, loading of the page's user code and execution of postback server-side events. After that, the page enters in rendering mode: the updated view state is collected; the HTML code is generated and then sent to the output console. Finally, the page is unloaded and the request is considered completely served.
从这里,我推断FrameworkInitlize()至少是在OnPreInit()之前被调用的。 但是仍然看不出来 FrameworkInitlize 的准确位置。
绕过上面所说的这些。有两种方法可以实现上述的要求。
方法一。在某页面的 InitializeCulture方法中设置你所需要的文化。比如
但这是针对某一个页面的。要应用到整个网站,就要多一点儿麻烦。要把这个 InitializeCulture方法写在 一个System.Web.UI.Page的子类中,然后让所有页面 的类继承于这个 子类而不是直接继承 System.Web.UI.Page 。
方法二。 在PreRequestHandlerExecute中设置你所需要的文化。参见 HttpApplication类的在线帮助:
An application executes events that are handled by modules or user code that is defined in the Global.asax file in the following sequence:
1. BeginRequest
2. AuthenticateRequest
3. PostAuthenticateRequest
4. AuthorizeRequest
5. PostAuthorizeRequest
6. ResolveRequestCache
An event handler (a page corresponding to the request URL) is created at this point.
7. PostResolveRequestCache
8. PostMapRequestHandler
9. AcquireRequestState
10. PostAcquireRequestState
11. PreRequestHandlerExecute
The event handler is executed.
12. PostRequestHandlerExecute
13. ...
我试过 BeginRequest, 但是不行。我想原因是因为Page.Request在此之后才被创建或赋值,所以在 BeginRequest中设置的文化 会被覆盖了。 直到 10. PostAcquireRequestState,才被准备好,只有在此之后我们才可以设置所需要的文化。
11和12之间的 "The event handler is executed."就应该是整个 页面 的生命周期的处理了。 方法一使用InitializeCulture就是在这里。
这样就能够达到最初的目的了。但是还有一个小问题。 按键的事件处理函数只会在设置了线程的文化之后才会被执行(不论是用PreRequestHandlerExecute,抑或InitializeCulture)。 结果就是在页面的HTML传到浏览器时,所要设的文化与 线程的文化不一样。 而在其他的事件发生时,由于 所要设的文化没有改变, 就会和线程的文化一样。 这样程序的行为就不一致了,容易使用户产生混淆。有一个不太完善的结局方法,就是在 按键的事件处理函数最后加上下面这句,这样用户就能立刻看到改变了的语言了 。
缺憾是由于当前页面要重新生成,原先的状态(比如用户已经输入的东西)就不会保留了。
另外还有一个与此相关的问题,就是如何本地化sitemap(网页导航?)。请参考下面这篇文章。
ASP.NET 2.0: 在使用web.sitemap时,如何本地化网页导航(sitemap)
很抱歉,有许多术语不知道准确的中文是什么,希望大家不吝赐教。
参考文章:
注:我用的是ASP.NET Beta 2。 参考文章列在最后。
参考第一篇文章, "Implicit Localization Expressions"一 节 。一个页面 ( Page ) 的本地化内容是在 FrameworkInitlize()中创建所有的控件时决定的。比如
button1.Text = ((string)
base.GetLocalResourceObject("LinkButtonResource1.Text"));
所以要在 FrameworkInitlize()之前设置好你所需要的页面的文化(Culture).
第二篇文章 " Page Lifecycle "一 节 列出了页面 的生命周期(Lifecycle )涉及的方法 。下面列出了从 页面 的构造函数( Constructor )开始与我的问题相关的一些方法。
Constructor
Construct
TestDeviceFilter
AddParsedSubObject
DeterminePostBackMode
OnPreInit
LoadPersonalizationData
InitializeThemes
OnInit
在第三篇文章"The Page Lifecycle"的开头写道:
Once the HTTP page handler class is fully identified, the ASP.NET run time calls the handler's ProcessRequest method to process the request. ... (it) begins by calling the method FrameworkInitialize, which builds the controls tree for the page. The method is a protected and virtual member of the TemplateControl class - the class from which Page itself derives. Any dynamically generated handler for an .aspx resource overrides FrameworkInitialize. In this method, the whole control tree for the page is built.
Next, ProcessRequest makes the page transit various phases: initialization, loading of view state information and postback data, loading of the page's user code and execution of postback server-side events. After that, the page enters in rendering mode: the updated view state is collected; the HTML code is generated and then sent to the output console. Finally, the page is unloaded and the request is considered completely served.
从这里,我推断FrameworkInitlize()至少是在OnPreInit()之前被调用的。 但是仍然看不出来 FrameworkInitlize 的准确位置。
绕过上面所说的这些。有两种方法可以实现上述的要求。
方法一。在某页面的 InitializeCulture方法中设置你所需要的文化。比如
public partial class _Default : System.Web.UI.Page
{
protected override void InitializeCulture()
{
string cul = Session["UICulture"];
if (!String.IsNullOrEmpty(cul))
{
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(cul);
}
}
}
{
protected override void InitializeCulture()
{
string cul = Session["UICulture"];
if (!String.IsNullOrEmpty(cul))
{
Thread.CurrentThread.CurrentUICulture =
new CultureInfo(cul);
}
}
}
但这是针对某一个页面的。要应用到整个网站,就要多一点儿麻烦。要把这个 InitializeCulture方法写在 一个System.Web.UI.Page的子类中,然后让所有页面 的类继承于这个 子类而不是直接继承 System.Web.UI.Page 。
方法二。 在PreRequestHandlerExecute中设置你所需要的文化。参见 HttpApplication类的在线帮助:
An application executes events that are handled by modules or user code that is defined in the Global.asax file in the following sequence:
1. BeginRequest
2. AuthenticateRequest
3. PostAuthenticateRequest
4. AuthorizeRequest
5. PostAuthorizeRequest
6. ResolveRequestCache
An event handler (a page corresponding to the request URL) is created at this point.
7. PostResolveRequestCache
8. PostMapRequestHandler
9. AcquireRequestState
10. PostAcquireRequestState
11. PreRequestHandlerExecute
The event handler is executed.
12. PostRequestHandlerExecute
13. ...
我试过 BeginRequest, 但是不行。我想原因是因为Page.Request在此之后才被创建或赋值,所以在 BeginRequest中设置的文化 会被覆盖了。 直到 10. PostAcquireRequestState,才被准备好,只有在此之后我们才可以设置所需要的文化。
11和12之间的 "The event handler is executed."就应该是整个 页面 的生命周期的处理了。 方法一使用InitializeCulture就是在这里。
这样就能够达到最初的目的了。但是还有一个小问题。 按键的事件处理函数只会在设置了线程的文化之后才会被执行(不论是用PreRequestHandlerExecute,抑或InitializeCulture)。 结果就是在页面的HTML传到浏览器时,所要设的文化与 线程的文化不一样。 而在其他的事件发生时,由于 所要设的文化没有改变, 就会和线程的文化一样。 这样程序的行为就不一致了,容易使用户产生混淆。有一个不太完善的结局方法,就是在 按键的事件处理函数最后加上下面这句,这样用户就能立刻看到改变了的语言了 。
Response.Redirect(Request.Path);
缺憾是由于当前页面要重新生成,原先的状态(比如用户已经输入的东西)就不会保留了。
另外还有一个与此相关的问题,就是如何本地化sitemap(网页导航?)。请参考下面这篇文章。
ASP.NET 2.0: 在使用web.sitemap时,如何本地化网页导航(sitemap)
很抱歉,有许多术语不知道准确的中文是什么,希望大家不吝赐教。
参考文章:
- ASP.NET 2.0 Localization Features: A Fresh Approach to Localizing Web Applications
- ASP.NET 2.0 Internals
- The ASP.NET Page Object Model