ASP.Net MVC 앱에서 문화 설정
ASP.net MVC 앱에서 Culture / UI Culture를 설정하는 가장 좋은 장소는 무엇입니까?
현재 다음과 같은 CultureController 클래스가 있습니다.
public class CultureController : Controller
{
public ActionResult SetSpanishCulture()
{
HttpContext.Session["culture"] = "es-ES";
return RedirectToAction("Index", "Home");
}
public ActionResult SetFrenchCulture()
{
HttpContext.Session["culture"] = "fr-FR";
return RedirectToAction("Index", "Home");
}
}
다음과 같은 링크가있는 홈페이지의 각 언어에 대한 하이퍼 링크 :
<li><%= Html.ActionLink("French", "SetFrenchCulture", "Culture")%></li>
<li><%= Html.ActionLink("Spanish", "SetSpanishCulture", "Culture")%></li>
잘 작동하지만 더 적절한 방법이 있다고 생각합니다.
다음 ActionFilter http://www.iansuttle.com/blog/post/ASPNET-MVC-Action-Filter-for-Localized-Sites.aspx를 사용하여 문화를 읽고 있습니다. 나는 약간의 MVC 멍청이이므로 올바른 위치에 설정하고 있다고 확신하지 못합니다. web.config 수준에서 수행하고 싶지 않습니다. 사용자의 선택을 기반으로해야합니다. 또한 브라우저 설정에서 문화를 얻기 위해 http 헤더를 확인하고 싶지 않습니다.
편집하다:
명확하게 말하면 세션 사용 여부를 결정하려는 것이 아닙니다. 나는 그 비트에 만족합니다. 내가 해결하려는 것은 각 Culture에 대한 작업 방법이 설정된 Culture 컨트롤러에서이 작업을 수행하는 것이 가장 좋은지 아니면 MVC 파이프 라인에 더 나은 위치가 있는지 여부입니다.
이 지역화 방법을 사용 하고 사용자가 example.com/xx-xx/를 방문 할 때마다 문화와 언어를 설정하는 경로 매개 변수를 추가했습니다.
예:
routes.MapRoute("DefaultLocalized",
"{language}-{culture}/{controller}/{action}/{id}",
new
{
controller = "Home",
action = "Index",
id = "",
language = "nl",
culture = "NL"
});
실제 문화 / 언어 설정을 수행하는 필터가 있습니다.
using System.Globalization;
using System.Threading;
using System.Web.Mvc;
public class InternationalizationAttribute : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
string language = (string)filterContext.RouteData.Values["language"] ?? "nl";
string culture = (string)filterContext.RouteData.Values["culture"] ?? "NL";
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));
}
}
Internationalization 속성을 활성화하려면 클래스에 추가하면됩니다.
[Internationalization]
public class HomeController : Controller {
...
이제 방문자가 http://example.com/de-DE/Home/Index 로 이동할 때마다 독일어 사이트가 표시됩니다.
이 답변이 올바른 방향으로 안내되기를 바랍니다.
또한 여기에서 찾을 수있는 작은 MVC 5 예제 프로젝트를 만들었습니다.
http : // {yourhost} : {port} / en-us / home / index로 이동하여 현재 날짜를 영어 (미국)로 확인하거나 http : // {yourhost} : {port} / de로 변경하세요. 독일어 등의 경우 -de / home / index.
나는 이것이 오래된 질문이라는 것을 알고 있지만 ModelBinder ( DefaultModelBinder.ResourceClassKey = "MyResource";
viewmodel 클래스의 데이터 주석에 표시된 리소스 와 관련하여) 와 관련 하여이 작업을 정말로 원한다면 컨트롤러 또는 심지어 ActionFilter
는 너무 늦었습니다. 문화를 설정합니다 .
문화는에서 설정할 수 있습니다 Application_AcquireRequestState
. 예를 들면 다음과 같습니다.
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
// For example a cookie, but better extract it from the url
string culture = HttpContext.Current.Request.Cookies["culture"].Value;
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
}
편집하다
실제로 Alex Adamyan이 블로그 에서 완벽하게 설명한 URL에 따라 문화를 설정 하는 사용자 지정 routehandler 를 사용하는 더 좋은 방법이 있습니다.
할 일은 GetHttpHandler
메서드 를 재정의 하고 문화를 설정하는 것입니다.
public class MultiCultureMvcRouteHandler : MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
{
// get culture from route data
var culture = requestContext.RouteData.Values["culture"].ToString();
var ci = new CultureInfo(culture);
Thread.CurrentThread.CurrentUICulture = ci;
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
return base.GetHttpHandler(requestContext);
}
}
나는 다음과 같이 컨트롤러의 Initialize 이벤트에서 그것을 할 것입니다 ...
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
const string culture = "en-US";
CultureInfo ci = CultureInfo.GetCultureInfo(culture);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
}
세션은 사용자별로 저장되는 설정이므로 정보를 저장하기에 적합한 장소입니다.
각 잠재적 문화에 대해 다른 작업 방법을 사용하지 않고 문화 문자열을 매개 변수로 사용하도록 컨트롤러를 변경합니다. 페이지에 링크를 추가하는 것은 쉬우 며 새로운 문화가 필요할 때마다 동일한 코드를 반복적으로 작성할 필요가 없습니다.
public class CultureController : Controller
{
public ActionResult SetCulture(string culture)
{
HttpContext.Session["culture"] = culture
return RedirectToAction("Index", "Home");
}
}
<li><%= Html.ActionLink("French", "SetCulture", new {controller = "Culture", culture = "fr-FR"})%></li>
<li><%= Html.ActionLink("Spanish", "SetCulture", new {controller = "Culture", culture = "es-ES"})%></li>
최고의 장소는 당신의 질문입니다. 가장 좋은 위치는 Controller.Initialize 메서드 내부 입니다. MSDN은 생성자 이후 및 작업 메서드 전에 호출된다고 씁니다. OnActionExecuting을 재정의하는 것과는 반대로 Initialize 메서드에 코드를 배치하면 클래스와 속성에 대한 모든 사용자 지정 데이터 주석 및 특성을 지역화 할 수 있습니다.
예를 들어 내 지역화 논리는 내 사용자 지정 컨트롤러에 삽입 된 클래스에서 나옵니다. 생성자 후에 Initialize가 호출되었으므로이 개체에 액세스 할 수 있습니다. 스레드의 문화 할당을 수행 할 수 있으며 모든 오류 메시지가 올바르게 표시되지는 않습니다.
public BaseController(IRunningContext runningContext){/*...*/}
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
var culture = runningContext.GetCulture();
Thread.CurrentThread.CurrentUICulture = culture;
Thread.CurrentThread.CurrentCulture = culture;
}
Even if your logic is not inside a class like the example I provided, you have access to the RequestContext which allow you to have the URL and HttpContext and the RouteData which you can do basically any parsing possible.
If using Subdomains, for example like "pt.mydomain.com" to set portuguese for example, using Application_AcquireRequestState won't work, because it's not called on subsequent cache requests.
To solve this, I suggest an implementation like this:
Add the VaryByCustom parameter to the OutPutCache like this:
[OutputCache(Duration = 10000, VaryByCustom = "lang")] public ActionResult Contact() { return View("Contact"); }
In global.asax.cs, get the culture from the host using a function call:
protected void Application_AcquireRequestState(object sender, EventArgs e) { System.Threading.Thread.CurrentThread.CurrentUICulture = GetCultureFromHost(); }
Add the GetCultureFromHost function to global.asax.cs:
private CultureInfo GetCultureFromHost() { CultureInfo ci = new CultureInfo("en-US"); // en-US string host = Request.Url.Host.ToLower(); if (host.Equals("mydomain.com")) { ci = new CultureInfo("en-US"); } else if (host.StartsWith("pt.")) { ci = new CultureInfo("pt"); } else if (host.StartsWith("de.")) { ci = new CultureInfo("de"); } else if (host.StartsWith("da.")) { ci = new CultureInfo("da"); } return ci; }
And finally override the GetVaryByCustomString(...) to also use this function:
public override string GetVaryByCustomString(HttpContext context, string value) { if (value.ToLower() == "lang") { CultureInfo ci = GetCultureFromHost(); return ci.Name; } return base.GetVaryByCustomString(context, value); }
The function Application_AcquireRequestState is called on non-cached calls, which allows the content to get generated and cached. GetVaryByCustomString is called on cached calls to check if the content is available in cache, and in this case we examine the incoming host domain value, again, instead of relying on just the current culture info, which could have changed for the new request (because we are using subdomains).
1: Create a custom attribute and override method like this:
public class CultureAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Retreive culture from GET
string currentCulture = filterContext.HttpContext.Request.QueryString["culture"];
// Also, you can retreive culture from Cookie like this :
//string currentCulture = filterContext.HttpContext.Request.Cookies["cookie"].Value;
// Set culture
Thread.CurrentThread.CurrentCulture = new CultureInfo(currentCulture);
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(currentCulture);
}
}
2: In App_Start, find FilterConfig.cs, add this attribute. (this works for WHOLE application)
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
// Add custom attribute here
filters.Add(new CultureAttribute());
}
}
That's it !
If you want to define culture for each controller/action in stead of whole application, you can use this attribute like this:
[Culture]
public class StudentsController : Controller
{
}
Or:
[Culture]
public ActionResult Index()
{
return View();
}
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if(Context.Session!= null)
Thread.CurrentThread.CurrentCulture =
Thread.CurrentThread.CurrentUICulture = (Context.Session["culture"] ?? (Context.Session["culture"] = new CultureInfo("pt-BR"))) as CultureInfo;
}
참고URL : https://stackoverflow.com/questions/1560796/set-culture-in-an-asp-net-mvc-app
'Program Tip' 카테고리의 다른 글
Ruby에서 배열의 마지막 요소를 얻는 방법은 무엇입니까? (0) | 2020.10.04 |
---|---|
iPhone-로컬 파일 URL의 NSData (0) | 2020.10.04 |
Python 스크립트는 터미널에서 명령을 실행합니다. (0) | 2020.10.04 |
Pandas 데이터 프레임 내의 열을 정수에서 문자열로 변환 (0) | 2020.10.04 |
출력에서 동일한 길이를 얻기 위해 printf ()를 사용하여 문자열을 포맷하는 방법은 무엇입니까? (0) | 2020.10.04 |