多语言MVC 4应用程序

时间:2013-08-25 15:34:31

标签: c# asp.net-mvc asp.net-mvc-4 localization

我正在创建一个新的应用程序,我想在一开始就做好,所以我可以在将来成长。

我已经看过几个指导如何制作多语言支持的应用程序的指南,但我无法弄清楚要使用的是什么。

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

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

我发现它们是存储语言数据的两种方式,无论是在db还是在资源文件中。 有什么利弊? 还有其他方式可供选择吗?

这就是我想要的:

  1. 易于维护(添加/更改/删除)
  2. 全语言支持。 (观点,货币,时间/日期,jquery,注释等等。)
  3. 启用更改语言。
  4. 自动检测语言。
  5. 未来安全。
  6. 这样做的首选方法是什么?有什么好的教程是2013年的最佳实践吗?

4 个答案:

答案 0 :(得分:13)

written a blog post汇总了多语言asp.net mvc应用程序的以下方面:

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

Url Routes:我通常会将文化保留在网址中,以便获得索引良好的ML网站。

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和JS文件,名为Lang-en.js,Lang-fr.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
  }
};

没有一种方法可以使用多语言网络应用。使用参数来翻译文本,可以在运行时快速交换。你有多个编辑器,可以打开那些你可以传递给翻译等的编辑器。

您可以查看博客文章并获取有关我如何执行此操作的详细示例。

答案 1 :(得分:1)

我基于db有自己的方法,但它可能不适合大型应用程序。

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

因此,每当我想渲染一个视图时,首先我从db中检索适当的转换,然后将其作为模型传递给视图:

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中检测并猜测他/她的地理位置并为他/她设置适当的语言

答案 2 :(得分: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来猜测用户想要的语言,这不是一个坏主意,但实际上取决于您的客户需求。

至于获得翻译,那真的取决于资源和数据库的起伏。因此,数据库的主要优点是,它易于在应用程序之间共享,如果您因任何原因需要更新短语,那么您可以通过一个数据库条目更新它们,但这也可能是一个错误,因为一些短语具有双重含义,并且在其他语言中可以完全不同地翻译,尽管在英语中使用相同的句子。 DB存在的另一个大问题是,在某种程度上(但这取决于实现),你会在VS中消除这些短语的智能。

资源当然具有适当的智能,但它们与您正在使用的Web应用程序相当静态,您无法在应用程序之间共享资源......不完全正确,但或多或​​少不能。虽然这种静态性质也是一个优点,因为所有资源都包含在应用程序中,并且您知道没有外部影响可以影响它。

实际上,这实际上取决于手头的项目。你只需要解决自己的利弊,为自己做出决定......对不起。但如果它有所帮助,我可以告诉你我公司的情况。我们制作了几个应用程序,它们在各种Web应用程序中共享相同的短语。我们曾经在DB中使用它,但是发生的事情是翻译保持阵列,这意味着客户要求使用西班牙语为一个应用程序提供更好的翻译,但这对其他应用程序没有任何意义。发生的事情比你想象的要多。然后我们转移到资源,但那里发生的事情是当一个应用程序的翻译被更新,然后没有人记得更新其他应用程序,实际上发生了3个不同的应用程序以3种不同的方式翻译相同的术语。最后我们决定回到数据库,因为能够立刻改变所有翻译对我们来说意味着更多,那么没有外部影响可以影响它。

一般来说,还有其他优点和缺点,但与上述相比,所有这些都是相当无关紧要的。你真的需要问你如何使用翻译。至于一般编辑(不包括上述点),那么aider方法同样适用,您可以使用这两种方法轻松更改,编辑或扩展翻译。

也就是说,如果数据库和数据库调用设计得很糟糕,那么使用资源可以更轻松地添加新语言,只需复制资源文件,将文化扩展名添加到名称中,然后将翻译添加到资源中即可。已完成,但又完全归结为数据库设计,因此在设计数据库时需要牢记这一点,并且对于在数据库中保存翻译一无所知。

总的来说,我会说资源更容易使用,并且非常容易维护和扩展(并且它们已经内置到.NET中),但如果您需要共享翻译,DB具有明显的优势。因此,如果我不得不说我会说推荐的方法是使用资源,但DB确实有它的位置,它实际上取决于项目。

答案 3 :(得分:0)

我一直在寻找与你相同的资源来满足相同的需求,但正如你所说,很难找到一个首选的解决方案。

但是我决定采用Michael Chambaud的解决方案,你已经在你的问题中联系了。这样做的原因是它很容易实现,给了我想要的网址,因为我还不是100%肯定......将来很容易更换。

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

听到你决定使用什么解决方案真的很有意思?