我正在尝试使用带有C#的ASP.NET开发一个MultiLanguage网站 我的问题是:我想让我的MasterPage支持在语言之间切换,但是当我把“InitializeCulture()”放在masterpage.cs中时,我收到了这个错误。
这是我的代码:
public partial class BasicMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Calendar1_DayRender(object sender, DayRenderEventArgs e)
{
if (e.Day.IsToday)
{
e.Cell.Style.Add("background-color", "#3556bf");
e.Cell.Style.Add("font-weight", "bold");
}
}
Dictionary<string, System.Globalization.Calendar> Calendars =
new Dictionary<string, System.Globalization.Calendar>()
{
{"GregorianCalendar", new GregorianCalendar()},
{"HebrewCalendar", new HebrewCalendar()},
{"HijriCalendar", new HijriCalendar()},
{"JapaneseCalendar", new JapaneseCalendar()},
{"JulianCalendar", new JulianCalendar()},
{"KoreanCalendar", new KoreanCalendar()},
{"TaiwanCalendar", new TaiwanCalendar()},
{"ThaiBuddhistCalendar", new ThaiBuddhistCalendar ()}
};
protected override void InitializeCulture()
{
if (Request.Form["LocaleChoice"] != null)
{
string selected = Request.Form["LocaleChoice"];
string[] calendarSetting = selected.Split('|');
string selectedLanguage = calendarSetting[0];
CultureInfo culture = CultureInfo.CreateSpecificCulture(selectedLanguage);
if (calendarSetting.Length > 1)
{
string selectedCalendar = calendarSetting[1];
var cal = culture.Calendar;
if (Calendars.TryGetValue(selectedCalendar, out cal))
culture.DateTimeFormat.Calendar = cal;
}
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
base.InitializeCulture();
}
}
如何创建基类?
答案 0 :(得分:12)
方法InitializeCulture()
仅存在于Page类,而不存在于MasterPage类,这就是您收到该错误的原因。
要解决此问题,您可以创建所有特定网页都继承的BasePage
:
BasePage
,或任何你想要的。BasePage
。以下是一个例子:
public class BasePage : System.Web.UI.Page
{
protected override void InitializeCulture()
{
//Do the logic you want for all pages that inherit the BasePage.
}
}
具体页面看起来应该是这样的:
public partial class _Default : BasePage //Instead of it System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//Your logic.
}
//Your logic.
}
答案 1 :(得分:9)
有一个替代解决方案,不要求您创建BasePage。
“文化”的问题在于它在页面生命周期的早期设置,所以Page.InitializeCulture
事件是页面上的早期事件之一(如果不是唯一的事件)我们可以挂机以更改Thread.CurrentThread.CurrentUICulture
。但是,只要请求在服务器上开始,我们就会更早地做到这一点。
我在每个请求上调用的Application_BeginRequest
文件的Global.asax
事件上执行此操作。
protected void Application_BeginRequest(Object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["langCookie"];
if (cookie != null && !string.IsNullOrEmpty(cookie.Value))
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(cookie.Value);
}
}
在那里,我检查是否存在一个包含我想要使用的文化的cookie。如果没有cookie,则将使用默认文化。
要更改我的应用程序上的语言,我只需要一个控件来更改客户端的cookie值,然后对服务器进行简单的回发。如果此类控件位于内容页面或母版页中并不重要,它甚至不需要服务器端的任何代码,因为所有处理都是在上述方法上完成的,并且cookie设置为客户端甚至在页面发布之前。
我使用了一个简单的LinkButton(它被设计为墨西哥国旗),但是你可以使用任何其他控件来点击/更改后进行回发。
<asp:LinkButton ID="btnSpanish" runat="server" OnClientClick="SetLanguageCookie('es')" CausesValidation="false" CssClass="mxFlag" />
在此按钮回发到服务器之前,它运行客户端点击事件,更新我想要设置的cookie值,瞧!
我有javascript代码在主页面部分设置cookie:
function SetLanguageCookie(selectedLanguage) {
var expDate = new Date();
expDate.setDate(expDate.getDate() + 20); // Expiration 20 days from today
document.cookie = "langCookie=" + selectedLanguage + "; expires=" + expDate.toUTCString() + "; path=/";
};
就是这样! Thread.CurrentThread.CurrentUICulture
已更改,不需要BasePage
类,也不会覆盖Page.InitializeCulture
方法。由于存储在cookie中,所以在访问后会记住所选语言的副作用。
如果您想使用DropDownList
而不是LinkButton
,请务必设置AutoPostBack="true"
,因为{{没有OnClientChanged
属性1}},您必须对DropDownList
上的onchange
属性进行硬编码,并将所选值传递给相同的javascript函数。
DropDownList
<asp:DropDownList ID="ddlLanguage" runat="server" AutoPostBack="true" onchange="SetLanguageCookie(this.options[this.selectedIndex].value)">
<asp:ListItem Text="English" Value="en" />
<asp:ListItem Text="Español" Value="es" />
<asp:ListItem Text="Français" Value="fr" />
</asp:DropDownList>
属性不是onchange
属性的一部分,但是,因为DropDownList
是DropDownList
控件的模拟控件,所以属性只是放置了'就像'渲染发生时一样,它在回发机制代码之前呈现。这是上面<select>
呈现的HTML:
DropDownList
希望有人发现这种方法和我一样有用。 :)