2012-06-18 7 views
6

사용자의 Accept-Language 헤더에 적절하게 대응해야하는 ASP.NET 웹 API 응용 프로그램이 있습니다.요청에 따라 언어 리소스를 동적으로 변경하는 좋은 방법

현재 문자열은 resx에 저장되고 Visual Studio의 생성 클래스를 통해 컴파일 안전 방식으로 액세스됩니다. 내가 뭘하고 싶은지 현재 접근 방식을 유지하고 resx의 각 번역 버전에 대한 위성 어셈블리를 만드는 것입니다. 그런 다음 사용자의 Accept-Language 헤더를 분석하여 사용자가 수락 한 언어를보고 위성 어셈블리에서 요청한 언어의 리소스를로드합니다. 비주얼 스튜디오을 담당하기 때문에

나는, 나는 ResourceSet의 도움으로 언어 별 ResourceManager 개체의 집합을 만들어 모든 행동 자신을 구현할 수 있지만, 다음은 컴파일시 안전을 유지하는 것이 가능하지 않을 것입니다 가정 resx 파일의 클래스를 자동으로 업데이트합니다.

지역화 된 언어 리소스를 동적으로 선택하는 가장 좋은 방법은 무엇입니까?

답변

10

질문을 읽는 동안 ASP.NET에서 자동으로 제공하지 않는 것은 아무것도 표시되지 않습니다. accept-language 요청 헤더를 사용하고 적절한 UICulture (ResourceManager에서 어떤 위성 어셈블리가로드되는지에 영향을 미칩니다)와 Culture (로케일 종속 형식화 및 구문 분석에 영향을주는 Culture)를 설정하도록 ASP.NET (WebForms 또는 MVC 여부)을 구성 할 수 있습니다. 날짜 및 숫자)를 적절히 입력해야합니다.

<globalization uiCulture="auto" culture="auto" /> 

상응하는 구성도 있습니다 :

이 같이 당신의 Web.config를 구성 (this MSDN page에 따라), 각 요청에 대해 UICulture와 문화 모두를 설정 accept-language 목록을 사용하도록 응용 프로그램을 구성하려면 페이지 당 설정.

그런 다음 Resource Fallback 프로세스에 따라 앱에 일치하는 문화권에 대한 위성 어셈블리가 포함되어 있거나 해당 부모 중립 문화가없는 위성 어셈블리가 있으면 리소스 관리자에서 사용하게됩니다. 그렇지 않은 경우 기본 리소스가 사용됩니다 (기본 언어 인 경우 영어).

+0

귀하의 게시물에서 다음과 같은 Accept-Language 헤더를 보내려고하면 : Accept-Language : it, de, en; q = 0.5' 그리고 ASP.NET은 요청 된 리소스를 이탈리아어로 찾을 수 없습니다. 다음에 독일어를 시도하지는 않지만 대신 중립적 인 문화로 돌아갑니다. 이 문제를 해결할 수있는 방법은 무엇입니까? –

+0

예, accept-language 헤더의 최상위 언어 (또는 적어도 유효한 .NET culture 이름 인 맨 위의 언어) 만 고려한 것 같습니다. 현지화가 가능한지 여부에 따라 더 똑똑하고 다른 도구를 사용하면 좋을 것입니다. 그러나 현지화 된 것을 진정으로 결정하는 것은 불가능합니다 (위성 어셈블리 방식은 한 가지 dll에 대해 독일어를 사용하고 한 dll에 대해 독일어를 사용하고 다른 하나에 대해 다른 하나의 이탈리아와 다른 것을로드 할 수 있음을 의미합니다) 대다수의 최종 사용자는 아마 하나에 대해서만 관심을 가질 것입니다. – Clafou

+0

즉, 나는 지난 주와 똑같은 문제가있어서이 "자동"설정의 대체를 구현했습니다. 내 경우에는 MVC 였고 OnActionExecuting에서이 문제를 처리했습니다. 모든 작업을 수행하는 것은 약간의 작업입니다. (얻을 수있는 것은 q 문법의 헤더 문자열뿐입니다. 구문 분석을 수행하고 .NET에서 culture 이름을 허용하지 않으므로 유효성을 검사해야합니다.) 나는 var orderedValidAcceptLanguages ​​= AcceptLanguage.Parse (httpContext.Request.Headers [ "Accept-Language"])와 같은 것으로 끝났다. (x => x.IsValid) .OrderByDescending (x => xQ) .ToList(); ' – Clafou

2

언어 헤더를 감지하고 현재 스레드 문화권을 설정하는 HttpModule을 쓸 수 있습니다.

public class LanguageModule : IHttpModule 
{ 
    public void Dispose() 
    { 
    } 

    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += new EventHandler(context_BeginRequest); 
    } 

    void context_BeginRequest(object sender, EventArgs e) 
    { 
     var application = sender as HttpApplication; 
     var context = application.Context; 
     var lang = context.Request.Headers["Accept-Language"]; 

     // eat the cookie (if any) and set the culture 
     if (!string.IsNullOrEmpty(lang)) 
     { 
      var culture = new System.Globalization.CultureInfo(lang); // you may need to interpret the value of "lang" to match what is expected by CultureInfo 

      Thread.CurrentThread.CurrentCulture = culture; 
      Thread.CurrentThread.CurrentUICulture = culture; 
     } 
    } 
} 

ResourceManager 등은 스레드 문화권에서 사용할 올바른 현지화 버전을 알아낼 것입니다.

+0

나는 [this] (http://stackoverflow.com/questions/4910159/how-are-iis7-threads-assigned/4910207#4910207) IIS에서 스레드 관리 및 내가 이해 한 것과 관련된 대답을 보았다. 단일 스레드가 여러 요청을 처리 할 수 ​​있습니다. 갈등이있는 것 같습니다. 그래도 테스트해야합니다. –

관련 문제