Had*_*asi 1 localization signalr
我有一个项目 mvc 4 c# 我正在使用资源文件进行本地化。我有改变文化的行动
public ActionResult ChangeCulture(string lang, string returnUrl)
{
if (lang.Equals("he-IL"))
{
CultureInfo ci = new CultureInfo(lang);
ci.DateTimeFormat.ShortDatePattern = "dd/MM/yy";
ci.DateTimeFormat.LongDatePattern = "dd/MM/yy";
ci.DateTimeFormat.LongTimePattern = "HH:mm";
ci.DateTimeFormat.ShortTimePattern = "HH:mm";
ci = new CultureInfo(lang);
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
}
else if (lang.Equals("en-US"))
{
CultureInfo ci = new CultureInfo(lang);
ci = new CultureInfo(lang);
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
}
else
{
return new HttpStatusCodeResult(404);
}
return Redirect(returnUrl);
}
Run Code Online (Sandbox Code Playgroud)
在视图中,我从资源中获取文本并且运行良好。
<div>@(ViewRes.GlobalResource.Hello)</div>
Run Code Online (Sandbox Code Playgroud)
但是当我从 SignalR 集线器返回文本时,它总是相同的语言。为什么?
SignalR 不会在其堆栈中本地化您的文本,您必须选择正确本地化的文本并自己返回该字符串。这应该就像从 a 请求您的资源ResourceManager并让它为您选择正确本地化的文本一样简单。一个非常简单的例子看起来像这样:
public string YourHubMethod()
{
ResourceManager resourceManager = new ResourceManager("YourNamespace.YourResourcesName",
typeof(YourHubType).Assembly);
return resourceManager.GetString("SomeResourceName");
}
Run Code Online (Sandbox Code Playgroud)
更新: 既然您已经在评论中提供了有关如何记住 Web 应用程序请求之间的当前文化的更多信息(您使用 cookie),我可以为您提供有关如何将此转移到 SignalR 的更多信息。
您首先要覆盖集线器的 OnConnected 属性,然后您可以提取 cookie 值并将其存储在 SignalR 连接状态中,如下所示:
public override Task OnConnected()
{
Client.Culture = Context.Request.Cookies["YourCultureCookieName"];
return base.OnConnected();
}
Run Code Online (Sandbox Code Playgroud)
一旦它存储在客户端状态中,您现在可以构建一个 HubPipelineModule 来查找该状态并为每个逻辑 SignalR 请求设置区域性:
public class CallerCulturePipelineModule : HubPipelineModule
{
protected override bool OnBeforeIncoming(IHubIncomingInvokerContext context)
{
// Use the value we stored in the Culture property of the caller's state when they connected
CultureInfo callerCultureInfo = new CultureInfo(context.Hub.Context.Caller.Culture);
Thread.CurrentThread.CurrentUICulture = callerCultureInfo;
Thread.CurrentThread.CurrentCulture = callerCultureInfo;
return base.OnBeforeIncoming(context);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您需要确保将管道模块注册为 Application_Start 的一部分:
GlobalHost.HubPipeline.AddModule(new CallerCulturePipelineModule());
Run Code Online (Sandbox Code Playgroud)
最后,如果用户在已经连接的情况下更改了他们的文化,您将需要使用新选择的值更新他们的连接状态(因为他们不会重新连接)。实际上无法在集线器本身之外修改连接状态,因此您需要实际获取IHubContext集线器的 ,并通过对现有 MVC 控制器ChangeCulture方法内的客户端的显式回调来更新客户端。为此,我建议您将连接 IDChangeCulture作为可选的查询字符串变量传递给(因为用户可能不会一直连接到您的集线器?),然后使用它来回调客户端:
string connectionId = <get connectionId from request here>;
IHubContext yourHubContext GlobalHost.GetHubContext<YourHub>();
yourHubContext.Client(connectionId).UpdateCultureState(lang);
Run Code Online (Sandbox Code Playgroud)
然后在客户端,您只需更新 JavaScript 中的状态:
yourHubProxy.client.updateCultureState = function(lang)
{
yourHubProxy.state.culture = lang;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1166 次 |
| 最近记录: |