ASP.NET MVC 3本地化 - Url.Content

3

我是一个ASP.NET MVC 3网站的助手,使用自定义路由来指定URL中的语言,如下所示:

routes.MapRoute("Default", "{culture}/{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", culture = "en", id = UrlParameter.Optional });

我的基础控制器会在其OnActionExecuting事件中适当设置当前线程的文化,如下所示:

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var culture = filterContext.RouteData.Values["culture"] ?? "en";
    var cultureInfo = CultureInfo.GetCultureInfo((string)culture);
    Thread.CurrentThread.CurrentCulture = cultureInfo;
    Thread.CurrentThread.CurrentUICulture = cultureInfo;
    base.OnActionExecuting(filterContext);
}

每当我需要在视图中使用特定于某个地区的字符串时,我会适当地引用资源:

<img src="@Url.Content(Resources.Paths.ChallengeLogo)" alt="@Resources.Strings.AltChallengeLogo" class="logo" />

然而,对于图片来说,URL(src =“ ...”)将遵循约定“〜/ Content / Culture / Images / Whatever.jpg”,我不想手动维护每个图像位置的资源文件。简而言之,我更喜欢做的是:

<img src="@Url.Content("Images/ChallengeLogo.png")" alt="@Resources.Strings.AltChallengeLogo" class="logo" />

在这种情况下,Url.Content方法会应用路径约定,并将src属性值转换为例如:
/Content/en-US/Images/ChallengeLogo.png
/Content/en-GB/Images/ChallengeLogo.png
/Content/de/Images/ChallengeLogo.png
etc...

我不一定非要使用Url.Content。我很乐意为此创建一个扩展方法,但我不确定我是否采取了最佳方法。这里的标准方法是什么?

编辑:最终我创建了一个辅助程序。该辅助程序具有检查当前文化路径是否存在或必要时回退到父/默认文化的附加好处。以下是代码:

private static CultureInfo _defaultCulture = CultureInfo.GetCultureInfo("en");

public static string Localized(this UrlHelper url, string pathTemplate)
{
    var server = url.RequestContext.HttpContext.Server;
    var culture = Thread.CurrentThread.CurrentUICulture;
    var localizedPath = string.Format(pathTemplate, culture.Name);
    var physicalPath = server.MapPath(localizedPath);

    while (!File.Exists(physicalPath) && culture.Parent != null)
    {
        culture = culture.Parent;
        localizedPath = string.Format(pathTemplate, culture.Name);
        physicalPath = server.MapPath(localizedPath);
    }

    if (!File.Exists(physicalPath))
        localizedPath = string.Format(pathTemplate, _defaultCulture.Name);

    return url.Content(localizedPath);
}

在我的看法中,我可以按照以下方式使用这个辅助工具:

<div class="toolbox">

    <a href="#" class="button register">
        <img src="@Url.Localized("~/Content/Localized/{0}/Images/Button_Register.png")" 
             alt="@Resources.Strings.AltRegisterButton" /></a>

    <a href="#" class="button login">
        <img src="@Url.Localized("~/Content/Localized/{0}/Images/Button_Login.png")" 
             alt="@Resources.Strings.AltLoginButton" /></a>

</div>
2个回答

3

最终我按照你的建议编写了一个辅助程序,但我将暂时不将答案归功于你,因为我想看看是否还有其他有趣的替代方案。 - Chris
如果所有本地化的图像都将始终位于相同的文件夹结构中,则可以像这样省略URL的第一部分@Url.Localized("Images/Button_Register.png")",并在帮助程序类中添加它。这将使其更短,更易于阅读。 - nickvane
我最终确实做到了那件事。谢谢! - Chris

0

嗯,我实际上还没有做过,但是当我在寻找实际完成此操作的人时,我遇到了这篇文章。

我想,您可以扩展StaticFileHandler,以便在提供实际文件之前先查找某个“本地化”版本的静态文件。

例如,在提供http://yoursite.com/Content/images/logo.jpg时:

  1. 修改请求的URL并查看是否存在/Content/images/es-ES/logo.jpg?
  2. 如果存在,则提供该文件
  3. 如果不存在,则回滚到默认文化或尝试在提供默认文化之前找到中性文化。

** 这可能与/Content/images/logo.jpg必须存在有关,因为这是触发StaticFileHandler的方式。

如果我最终这样做了,我会撰写一篇博客文章并在此处分享链接。

更新:我已经按照我所说的实现了它,尽管它最终成为了一种自定义的HttpHandler,而不是StaticFileHandler的扩展:http://www.prosoftnearshore.com/2011/10/localizing-files-jpg-css-js-etc-in-asp-net/


有趣的方法。这样做可以消除确定备用文化的需要 - 原始位置是默认值 - 也不必使视图具有文化意识。我喜欢它! - Chris
链接已经失效,我无法通过搜索找到它。你的帖子还在网上吗? - NightOwl888
@NightOwl888 刚刚更新了帖子并附上了URL。抱歉耽搁了。 - Mauricio Morales

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接