【问题标题】:How do you localize/internationalize an MVC Controller when using a SQL based localization provider?使用基于 SQL 的本地化提供程序时,如何本地化/国际化 MVC 控制器?
【发布时间】:2026-01-04 06:10:02
【问题描述】:

希望这不是一个太愚蠢的问题。在 MVC 中,视图中似乎有很多本地化支持。但是,一旦我到达控制器,它就会变得模糊不清。

  • 使用 meta:resourcekey="blah" 已淘汰,与 相同。
  • ASP.NET MVC - Localization Helpers -- 建议对 Html 助手类进行扩展,例如 Resource(this Controller controller, string expression, params object[] args)。同样,Localize your MVC with ease 建议使用稍微不同的扩展名,例如 Localize(this System.Web.UI.UserControl control, string resourceKey, params object[] args)

这些方法在控制器中都不起作用。我将以下函数放在一起,并使用控制器的完整类名作为我的 VirtualPath。但我是 MVC 的新手,我认为有更好的方法。

    public static string Localize (System.Type theType, string resourceKey, params object[] args) {
         string resource = (HttpContext.GetLocalResourceObject(theType.FullName, resourceKey) ?? string.Empty).ToString();
         return mergeTokens(resource, args);
    }

想法?评论?

【问题讨论】:

  • 我认为本地化是不应该成为控制器逻辑一部分的一个方面。由于这是一个特定于演示的方面,我认为无论您选择哪种方法,您都应该让您的视图负责解决这个问题。我知道这并不能回答您的问题,但至少可以提示您做出决定。
  • @uvita 请查看我对@LukLed 的回复。我还想补充一点,将本地化作为视图的一个问题是一个合理的架构决策,尽管这种类型的策略迫使我在我的控制器或验证服务层中收集一个键/令牌列表,以便它们可以在我的视图中传递通过 ViewData。此外,据我所知,这意味着我的视图将不得不填充 ModelState 错误或放弃 Html.ValidationMessage() 基础结构。这不会比在服务层中本地化更破坏视图的职责吗?

标签: asp.net-mvc model-view-controller localization internationalization


【解决方案1】:

我有同样的question。这篇博文展示了解决问题的不同方法:http://carrarini.blogspot.com/2010/08/localize-aspnet-mvc-2-dataannotations.html

最后我使用了一个 T4 模板来生成一个资源类。我还有一个 HtmlHelper 方法来访问我的资源:

public static string TextFor(this HtmlHelper html, string resourceName, string globalResourceName, params object [] args)
{
    object text = HttpContext.GetGlobalResourceObject(globalResourceName, resourceName);
    return text != null ? string.Format(text.ToString(), args) : resourceName;
}

另一个版本从 Controller 和 View 生成本地化版本:

public static string LocalTextFor(this HtmlHelper html, string resourceName, params object [] args)
{
    string localResourceName = string.Format("{0}.{1}", html.ViewContext.RouteData.Values["controller"],
                                                 html.ViewContext.RouteData.Values["action"]);
    object text = HttpContext.GetGlobalResourceObject(localResourceName, resourceName);
    return text != null ? string.Format(text.ToString(), args) : langName;
}

【讨论】:

  • 这类似于我最终实现的(去年!)。但是你得到了第一个写出来的答案投票:-)
【解决方案2】:

我使用 PublicResXFileCodeGenerator 作为自定义工具(在 .resx 文件的属性中选择)使用强类型资源。如果我有带有“AreYouSure”名称和“你确定吗?”的资源值,它可以通过在控制器和视图中调用ResourceClass.AreYouSure 来访问。效果很好。

【讨论】:

  • 我很高兴听到其他消息,但这需要在程序集中嵌入资源文件(它会自动生成您依赖的类)。我的资源存储在数据库中,因此此解决方案不起作用。
【解决方案3】:

您想在控制器中本地化什么?通常只有向用户显示的内容应该被本地化。向用户显示的内容应该在视图中,以便返回给助手。

【讨论】:

  • 例如验证消息。也许不在控制器中,而是在服务层中。
  • 具体来说,我正在查看 MVC Starter Kit 和 MVC 2 创建的默认项目。在两者中,控制器中都有一系列用户名/密码验证语句和错误消息。我正在寻找一种适当的方法来本地化这些类型的语句。我同意(与@LukLed 和@uvita 一起),在较大的项目中,服务层是更合适的验证位置。但是,我不想使我的问题的描述复杂化。然而,答案同样适用于控制器和服务层。
  • 是的,示例 MS 项目不会将非英语使用者视为用户 :) 无论如何,为什么不设置消息,而不仅仅是设置代码以供以后查找正确留言?
最近更新 更多