다국어 사이트는 다음을 번역해야 합니다.
언어 전환이 쉬워야 합니다.
더 많은 언어를 추가하는 것은 상대적으로 쉬워야 합니다.
ASP.NET MVC 5 프로젝트 예제는 https://github.com/mchudinov/AspMvc5Multilingual에서 다운로드할 수 있습니다.

Add lang parameter to routes in RegisterRoutes method of RouteConfig class. Set constraints to enabled languages. Set default language in default route.
한국어와 영어를 사용하기 위해 constraints 를 사용하여 제한을 걸어 en|ko 로 설정했습니다.
RouteConfig 클래스의 RegisterRoutes 메서드 에서 경로에 lang 매개변수를 추가 합니다. 사용 가능한 언어로 제약 조건을 설정합니다. 기본 경로에서 기본 언어를 설정합니다.
public class RouteConfig
{
	public static void RegisterRoutes(RouteCollection routes)
	{
		routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
		routes.MapRoute(
			name: "Language",
			url: "{lang}/{controller}/{action}/{id}",
			defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional },
			constraints: new { lang = @"ru|en" }
		);
		routes.MapRoute(
			name: "Default",
			url: "{controller}/{action}/{id}",
			defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional, lang = "en" }
		);
	}
}
Culture 는 컨트롤러의 Initialize 메서드 또는 filter attribute. 을 사용하는 두 가지 방법으로 활성화할 수 있습니다.
언어 데이터가 필요한 모든 컨트롤러는 Initialize 메서드에서 culture 을 초기화 해야 합니다 . 기본 컨트롤러 클래스를 만들고 그 안에 있는 Initialize 메서드를 재정의해 보겠습니다 .
/// <summary>
/// 생성자가 호출될 때 사용하지 못할 수 있는 데이터를 초기화합니다.
/// 다국어 설정 luckshim
/// </summary>
/// <param name="requestContext">HTTP 컨텍스트 및 경로 데이터입니다.</param>
/// <exception cref="NotSupportedException">Invalid language code '{CurrentLanguageCode}'.</exception>
protected override void Initialize(RequestContext requestContext)
{
    if (requestContext.RouteData.Values["lang"] != null && requestContext.RouteData.Values["lang"] as string != "null")
    {
        CurrentLanguageCode = (string)requestContext.RouteData.Values["lang"];
        if (CurrentLanguageCode != null)
        {
            try
            {
                Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(CurrentLanguageCode);
                //NumberFormatInfo nfi = new NumberFormatInfo { CurrencySymbol = "£" };
                //Thread.CurrentThread.CurrentUICulture.NumberFormat = Thread.CurrentThread.CurrentCulture.NumberFormat = nfi;
            }
            catch (Exception)
            {
                throw new NotSupportedException($"Invalid language code '{CurrentLanguageCode}'.");
            }
        }
    }
    base.Initialize(requestContext);
    ViewBag.CurrentLanguageCode = CurrentLanguageCode;
}
다른 모든 언어 종속 컨트롤러는 이 기본 컨트롤러 클래스에서 상속되어야 합니다.
ActionFilterAttribute 에서 상속된 LocalizationAttribute 클래스를 만듭니다 .
public class LocalizationAttribute : ActionFilterAttribute
{
	private readonly string _defaultLanguage;
	public LocalizationAttribute(string defaultLanguage)
	{
		_defaultLanguage = defaultLanguage;
	}
	public override void OnActionExecuting(ActionExecutingContext filterContext)
	{
		string lang = (string)filterContext.RouteData.Values["lang"] ?? _defaultLanguage;
		if (lang != null)
		{
			try
			{
				Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = new CultureInfo(lang);
			}
			catch (Exception)
			{
				throw new NotSupportedException($"Invalid language code '{lang}'.");
			}
		}
	}
}
App_Start의 폴더에 FilterConfig의 에 클래스를 추가하고, LocalizationAttribute 을 생성합니다.
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new LocalizationAttribute("en"), 0);
        }
    }
언어 정보가 필요한 모든 컨트롤러에서 [Localization] 속성을 사용 하십시오.
[Localization("en")]
public class DefaultController : Controller
{
	public ActionResult Index()
	{
		return View();
	}
}
Asp_Net 폴더 App_LocalResources 를 프로젝트에 추가합니다 . 리소스 파일이 여기에 배치됩니다.

기본 언어(내 경우 영어)에 대한 언어 리소스 파일 GlobalRes.resx 와 GlobalRes와 같은 다른 언어에 대한 파일을 추가합니다. ru .resx를 App_LocalResources 폴더로 이동합니다. 파일 이름의 두 글자는 RegionInfo.TwoLetterISORegionName Property 에 정의된 대로 지역 정보 ISO(국가 코드) 여야 합니다. 지역 코드의 전체 목록은 Wikipedia 페이지 ISO 3166-1 alpha-2 에서 찾을 수 있습니다 .

이 네임스페이스를 표준 ~/Web.config 파일이 아닌 ~/Views/web.config 파일에 추가했는지 확인하십시오 .
  <system.web.webPages.razor>
    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
...
        <add namespace="AspMvc5Multilingual.App_LocalResources" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>
모델의 클래스 이름에 대한 번역을 정의하는 DisplayAttribute :
[Display(Name = "Name", ResourceType = typeof(GlobalRes))]
유효성 검사 메시지에 ErrorMessageResourceType 및 ErrorMessageResourceName 을 사용 합니다.
ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "This_field_is_required")
public class Widget
{
	[Required(ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "This_field_is_required")]
	[StringLength(50, MinimumLength = 5, ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "Must_be_at_least_5_charachters")]
	[RegularExpression(@"^[A-Za-z0-9_]+$", ErrorMessageResourceType = typeof(GlobalRes), ErrorMessageResourceName = "Must_contain_only_letters")]
        [Display(Name = "Name", ResourceType = typeof(GlobalRes))]
	public string Name { get; set; }
}
GlobalRes를 사용하십시오 . Razor 파일에서 참조 이름 변경:
@model AspMvc5Multilingual.Models.Widget
@Html.ActionLink(GlobalRes.MainMenu, "Index", "Default", null, new { title = GlobalRes.Tooltip_help })
<br/>
    @GlobalRes.Money: @($"{Model.Money:c0}") <br/>
    @GlobalRes.DateAndTime: @Model.DateTime.ToString("F") <br/>
<br/>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(false, "")
    <div>
        @Html.LabelFor(model => model.Name, GlobalRes.Label_text)
        @Html.EditorFor(model => model.Name)
        @Html.ValidationMessageFor(model => model.Name, "")
    </div>
    <input type="submit" value="@GlobalRes.Submit_and_test_error_messages" />
}
라우팅을 기반으로 언어 링크를 생성하는 다음 도우미 클래스를 사용합니다. UrlHelper 확장 메소드를 생성 합니다.
public static class LanguageHelper
{
	public static MvcHtmlString LangSwitcher(this UrlHelper url, string Name, RouteData routeData, string lang)
	{
		var liTagBuilder = new TagBuilder("li");
		var aTagBuilder = new TagBuilder("a");
		var routeValueDictionary = new RouteValueDictionary(routeData.Values);
		if (routeValueDictionary.ContainsKey("lang"))
		{
			if (routeData.Values["lang"] as string == lang)
			{
				liTagBuilder.AddCssClass("active");
			}
			else
			{
				routeValueDictionary["lang"] = lang;
			}
		}
		aTagBuilder.MergeAttribute("href", url.RouteUrl(routeValueDictionary));
		aTagBuilder.SetInnerText(Name);
		liTagBuilder.InnerHtml = aTagBuilder.ToString();
		return new MvcHtmlString(liTagBuilder.ToString());
	}
}
예를 들어 _Layout.cshtml 에서 언어 링크 사용
@using AspMvc5Multilingual.Helper
<!DOCTYPE html>
<html>
    <head>
...
    </head>
    <body>
        <ul>
            @Url.LangSwitcher("English", ViewContext.RouteData, "en")
            @Url.LangSwitcher("Russian", ViewContext.RouteData, "ru")
        </ul>
        <div>
            @RenderBody()
        </div>
    </body>
</html>
System.Globalization.NumberFormatInfo 클래스는 숫자 값의 서식 지정 및 구문 분석을 위한 culture-specific 정보를 제공합니다. 사용하기가 매우 쉽습니다.
NumberFormatInfo nfi = new NumberFormatInfo {CurrencySymbol = "€"};
string.Format(nfi,"{0:c0}",12345);
NumberFormatInfo nfi = new NumberFormatInfo { CurrencySymbol = "£" };
Thread.CurrentThread.CurrentUICulture.NumberFormat = Thread.CurrentThread.CurrentCulture.NumberFormat =
https://blog.chudinov.net/setup-a-multilingual-site-using-asp-net-mvc5/
Setup a multilingual site using ASP.NET MVC5
A multilingual site should translate the following: Date and time formatting Currency Text resources: lables, buttons, validation messages, tooltips It must be easy to switch languages. It should b…
blog.chudinov.net