多语言MVC 4应用程序

17

我现在正在创建一个新的应用程序,我希望从一开始就把所有事情做好,以便未来能够扩展。

我查看了几个指南,描述了如何创建支持多语言的应用程序,但我无法确定使用哪个。

一些教程已经过时,我不知道它们是否过时。

http://www.codeproject.com/Articles/352583/Localization-in-ASP-NET-MVC-with-Griffin-MvcContri http://geekswithblogs.net/shaunxu/archive/2012/09/04/localization-in-asp.net-mvc-ndash-upgraded.aspx http://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx http://www.chambaud.com/2013/02/27/localization-in-asp-net-mvc-4/ https://github.com/turquoiseowl/i18n

我发现有两种存储语言数据的方法,一种是在数据库中,另一种是在资源文件中。这两种方法各有利弊?是否有其他更好的方法?

这就是我想要的:

  1. 易于维护(添加/更改/删除)
  2. 完整的语言支持。(视图,货币,时间/日期,JQuery,注释等等..)
  • 可以更改语言。
  • 自动检测语言。
  • 未来安全。
  • 做这个的首选方式是什么?有没有任何好的教程是2013最佳实践?

    4个回答

    13

    我已经写了一篇博客文章,涵盖了多语言asp.net mvc应用程序的以下方面:

    数据库:我将表分为两个部分,一个包含不可翻译的字段,另一个包含需要翻译的字段。

    Url路由:通常我会在URL中保留语言环境,这样可以获得良好的多语言站点索引。

    routes.MapRoute(
      name: "ML",
      url: "{lang}/{controller}/{action}/{id}",
      defaults: new { lang = "en-CA", controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
    

    你可以从一个基础控制器类中使{lang}参数在你的控制器中可用。有关所有详细信息,请参见博客文章。

    查询数据: 你只需将Culture传递给你的存储库或数据库上下文。思路是创建一个视图模型,合并你为翻译而分开的两个表格。

    public ActionResult Index(string id)
    {
        var vm = pages.Get(id, Language); // Language is the {lang} from the route
        return View(vm);
    }
    
    您的看法:使用带有通用两位字母语言代码的.NET资源文件,例如:HomePage.en.resx,HomePage.fr.resx。区域设置en**-US**,en**-CA**可用于格式化货币、日期、数字等。您的资源文件很可能对英语美国、加拿大等都是相同的。 图片:使用像imagename-en.png,imagename-fr.png这样的格式。从您的视图中通过扩展方法使{lang}路由参数可用,并像这样显示您的图像:
    <img src="/content/logos/imagename-@this.CurrentLanguage()" />
    

    你也可以为支持的语言单独创建一个完整的文件夹。例如:/content/en/imagename.png、/content/fr/imagename.png。
    JavaScript:我通常创建一个名为LanguagePacks的文件夹和名为Lang-en.js、Lang-fr.js的JS文件。这个想法是创建一个“静态”类,你可以在其他JS文件中使用它。
    // lang-en.js
    var Lang = {
      globalDateFormat = 'mm-dd-yy';
      greeting: 'Hello'  
    };
    

    在您的视图中,加载正确的语言文件。
    <script type="text/javascript" src="/content/js/languagepacks/lang-@(this.CurrentLanguage()).js"></script>
    

    从JavaScript模块中

    // UI Module
    var UI = function() {
    
      function notify() {
        alert(Lang.greeting);
      }
      return {
        notify: notify
      }
    };
    

    制作多语言 Web 应用没有唯一的方法。使用资源来翻译您的文本,它们可以在运行时快速交换。您有多个编辑器可以打开这些资源文件,以便您可以将其传递给翻译人员等。

    您可以查看博客文章并获取详细示例,了解我如何实现此功能。


    1

    我有一种基于数据库的方法,但对于大规模应用可能不太适合。

    我创建了一个名为Translation的表/实体来保存应该是多语言的标题和文本。

    因此,每当我想呈现视图时,首先从数据库中检索适当的翻译,然后将其作为模型传递给视图:

    var t = dbCtx.Translations.Find(langID);
    // ...
    return View(t);
    

    然后在视图中,我将内容呈现如下:

    <tr>
        <td>@Html.DisplayFor(m => m.WelcomeMessage)</td>
        <td>@Url.Action(Model.EnterSite, "Index", "Home")</td>
    </tr>
    

    关于获取适当的答案,你有几种方法。你可以使用会话:

    Session["Lang"] = "en";
    // ...
    var lang = (string)Session["Lang"] ?? "en";
    

    或者通过查询字符串传递,或者它们的组合。

    对于自动检测语言,您应该决定以下内容:

    a)从浏览器中检测

    b)从用户IP地址和猜测其地理位置,并为其设置适当的语言


    1
    我有一种感觉,这个问题没有一个直截了当的答案。对于格式和其他方面,您应该始终使用CultureUICulture,例如“en-GB”表示英式英语,“en-US”表示美式英语(是的,它们之间有区别)。整个.Net都是围绕它构建的,这样您就可以使用本地格式而不用考虑太多。您还应该查看System.Globalization命名空间以获取更多详细信息: http://msdn.microsoft.com/en-us/library/system.globalization%28v=vs.110%29.aspx 关于文化应该来自哪里,至少在我们公司中,政策总是来自查询字符串,毫无例外。原因是如果您使用IP本地化,例如,如果一个西班牙用户正在日本查看西班牙网站,然后会切换到日语版本,那么不完全错误但可能会让人感到烦恼,如果您告诉客户这是直接的西班牙链接或其他什么东西。话虽如此,如果在查询字符串中未定义文化,则使用IP猜测用户想要的语言也不是坏主意,但这确实取决于您客户的需求。
    至于获取翻译的位置,则真的取决于资源和数据库各有优缺点。因此,数据库的主要优点是,易于在应用程序之间共享,如果由于任何原因需要更新短语,则可以通过一个数据库条目更新所有短语,但这也可能是一个问题,因为某些短语具有双重含义,并且在其他语言中可以完全不同地翻译,尽管英语使用相同的句子。数据库的另一个大问题是,在某种程度上(但这取决于实现方式),您会失去VS对短语的智能。
    课程资源确实有适当的智能,但它们相对于您正在使用的Web应用程序是相当静态的,您无法跨应用程序共享资源...嗯,不完全正确,但或多或少是这样。虽然这种静态性质也是一个优点,因为所有资源都包含在应用程序中,您知道没有外部影响可以影响它。
    实际上,这真的取决于手头的项目。你只需要权衡利弊,自己做出决定...抱歉。但如果有帮助的话,我可以告诉你我的公司是怎么做的。我们制作了几个应用程序,这些应用程序在各种Web应用程序中共享相同的短语。我们曾经将其放在数据库中,但发生的情况是翻译一直失控,意味着客户要求在一个应用程序中提供更好的西班牙语翻译,但在其他应用程序中根本没有意义。这种情况比你想象的要多。然后我们转向了资源,但那里发生的情况是当一个应用程序的翻译更新时,然后没有人记得更新其他应用程序,实际上发生了3个不同的应用程序以3种不同的方式翻译了相同的术语。最后,我们决定回到数据库,因为一次更改所有翻译的能力对我们来说比没有外部影响的事实更重要。
    总的来说,还有其他优缺点,但与上述相比都不太相关。你确实需要问一下你如何使用翻译。至于一般编辑(不包括上述要点),则aider方法同样有效,你可以很容易地使用两种方法更改、编辑或扩展翻译。

    话虽如此,如果数据库和数据库调用设计得不好,那么使用资源添加新语言可能会更加容易,只需复制资源文件,添加文化扩展名并将翻译添加到资源中即可完成,但这完全取决于数据库设计,因此在设计数据库时要牢记这一点,它几乎没有关于将翻译保存在数据库中的内容。

    总的来说,我想说资源更易于使用,非常易于维护和扩展(并且已经内置于.NET中),但是如果需要共享翻译,则DB具有明显优势。因此,如果必须选择,我建议使用资源,但是DB确实有其位置,这取决于项目。


    0

    我也像你一样为同样的需求查找了相同的资源,但正如你所说很难找到一个优选的解决方案。

    但是我决定采用Michael Chambaud的解决方案,这是你在问题中链接的。原因是它易于实现,给了我想要的url,并且由于我仍然不确定...将来易于替换。

    除此之外,我将使用jquery globalize进行客户端格式化。

    真的很有趣听到你选择了哪个解决方案?


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