다음을 통해 공유


다중 언어를 지원하는 솔루션 만들기

 

게시 날짜: 2017년 1월

적용 대상: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

Microsoft Dynamics 365(온라인 및 온-프레미스)은 다국어를 지원합니다. 다른 기본 언어를 포함하거나 다국어가 프로비전된 조직에 대해 솔루션을 설치하려는 경우 솔루션을 계획할 때 이를 고려하십시오. 다음 표에는 다국어를 지원하는 솔루션에 포함할 솔루션 구성 요소와 함께 사용할 수 있는 방법이 나와 있습니다.

방법

솔루션 구성 요소 유형

개발자 옵션

웹 리소스

포함된 레이블

응용 프로그램 탐색(사이트 맵)
리본

번역 가져오기 및 내보내기

특성
차트
대시보드
엔터티
엔터티 관계
양식
메시지
옵션 집합
보기

기본 언어 문자열 지역화

계약 템플릿
연결 역할
프로세스(워크플로)
보안 역할
필드 보안 프로필

지역화 필요 없음

SDK 메시지 처리 단계
서비스 끝점

각 언어에 대한 별도 구성 요소

문서 템플릿
전자 메일 템플릿
편지 병합 템플릿
보고서
대화

언어 리소스로 XML 웹 리소스 사용

플러그 인 어셈블리

다음 섹션에서는 각 방법에 대한 추가 정보를 제공합니다.

개발자 옵션

웹 리소스에는 사용자 인터페이스에서 설정할 수 있지만 응용 프로그램에서 사용되지 않는 LanguageCode 특성이 있습니다. 웹 리소스는 URL 주소 지정이 가능하므로 조건에 따라 LanguageCode로 사용 가능한 웹 리소스를 쿼리하는 대신 일반적으로 이름으로 웹 리소스에 액세스합니다. 따라서 LanguageCode는 제한된 값입니다. 더 일반적인 시나리오는 웹 리소스가 표시되는 컨텍스트에 따라 적절한 언어를 검색해야 하는 것입니다. 웹 리소스의 경우 컨텍스트 개체는 getOrgLcidgetUserLcid 함수에 대한 액세스 권한을 제공합니다. 두 함수 모두 로캘 ID(LCID) 값에 해당하는 정수 값을 반환합니다.유효한 로캘 ID 값은 LCID(로캘 ID) 차트에서 확인할 수 있습니다.

사용자 인터페이스에 텍스트를 표시하는 웹 리소스의 경우 텍스트 및 레이아웃에 사용자의 언어 기본 설정을 지원하는 방식을 관리하는 모든 방법을 사용할 수 있습니다. 특정 구현은 웹 리소스 유형에 따라 달라집니다.

HTML 웹 리소스

한 가지 옵션은 적용된 이름에 따라 별도의 다양한 지역화된 웹 리소스를 만드는 것입니다. 예를 들어 영어를 지원하기 위해 new_/my_solution/1033/content.htm이라는 웹 리소스를 사용하고 일본어를 지원하기 위해 new_/my_solution/1041/content.htm라는 웹 리소스를 사용할 수 있습니다. 오른쪽에서 왼쪽 방향이 필요한 언어의 경우 방법: 전역화를 위해 HTML 태그를 사용하여 오른쪽에서 왼쪽으로 텍스트 표시를 참조하십시오.

사용자의 언어에 따라 UI 텍스트를 동적으로 설정할 수 있도록 하려면 스크립트 웹 리소스 파일에서 정의된 한 개체에 지역화된 문자열 값을 모두 저장합니다. 사용자의 언어 기본 설정에 따라 페이지가 로드될 때 해당 개체에 저장된 문자열을 사용하여 UI 텍스트 요소를 설정할 수 있습니다. 다음 JavaScript 코드 샘플은 지역화된 문자열을 설정하는 방법을 보여 줍니다.

var userLcid = 1033;

var localizedStrings = {
 ErrorMessage: {
  _1033: "There was an error completing this action. Please try again.",
  _1041: "このアクションを完了、エラーが発生しました。もう一度実行してください。",
  _1031: "Es ist ein Fehler aufgetreten, der Abschluss dieser Aktion. Bitte versuchen Sie es erneut.",
  _1036: "Il y avait une erreur complétant cette action. Veuillez essayer à nouveau.",
  _1034: "Hubo un error al completar esta acción. Vuelva a intentarlo.",
  _1049: "Произошла ошибка, выполнение этого действия. Пожалуйста, попробуйте снова."
 },
 Welcome: {
  _1033: "Welcome",
  _1041: "ようこそ",
  _1031: "Willkommen",
  _1036: "Bienvenue",
  _1034: "Bienvenido",
  _1049: "Добро пожаловать"
 }
};
var LocalizedErrorMessage = localizedStrings.ErrorMessage["_" + userLcid];
var LocalizedWelcomeMessage = localizedStrings.Welcome["_" + userLcid];

Silverlight 웹 리소스

지역화된 언어 리소스를 지원하기 위해 Silverlight 응용 프로그램을 작성할 수 있습니다.추가 정보:Silverlight 기반 응용 프로그램 지역화.

다음 클래스는 Silverlight 웹 리소스가 표시되는 컨텍스트에 따라 사용자의 언어 기본 설정에 대한 액세스 권한을 제공합니다. 이 클래스는 영어, 아랍어, 독일어, 히브리어 및 일본어를 지원합니다.Silverlight 웹 리소스에서 지원되는 특정 언어에 대해 수정해야 합니다.

public static class Localization    
    {
    // The locale ID.
    public static int LCID { get; set; }
    // Create a dictionary of right-to-left language codes (Hebrew and Arabic).
    private static Dictionary<int, bool> _rightToLeftLanguages =
        new Dictionary<int, bool>
        {
            { 1025, true },
            { 1037, true },
        };
    private static Dictionary<int, String> _lcidToCultureNameMap =
        new Dictionary<int, String>
        {
            { 1025, "ar-SA" },
            { 1031, "de-DE" },
            { 1033, "en-US" },
            { 1037, "he-IL" },
            { 1041, "ja-JP" }
        };
    public static void InitializeCulture()
    {
        // Get the user's LCID from the page's context to determine what language to
        // display.
        dynamic window = HtmlPage.Window;
        //Get the user's language code from the context.
        try
        {
            //If the containing window is a CRM form
            LCID = Convert.ToInt32(window.Xrm.Page.context.getUserLcid());
            // For testing, comment the line above and uncomment one of the lines below
            //representing a user language.
            //LCID = 1033; //English
            //LCID = 1041; //Japanese
            //LCID = 1031; //German
            //LCID = 1037; //Hebrew - a right-to-left language.
            //LCID = 1025; //Arabic - a right-to-left language.
        }
        catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
        {
            try
            {
                //If the containing window is a CRM web resource with
                //the WebResources/ClientGlobalContext.js.aspx page linked
                LCID = Convert.ToInt32(window.GetGlobalContext().getUserLcid());
            }
            catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException)
            {
                LCID = 1033; //Setting a default for design time when the context
                //object is not present and one of the sample languages are not set.
            }
        }
        // Sets the culture of the thread to the appropriate culture, based on what
        // LCID was retrieved.
        if (_lcidToCultureNameMap.ContainsKey(LCID))
        {
            var culture = new CultureInfo(_lcidToCultureNameMap[LCID]);
            Thread.CurrentThread.CurrentCulture = culture;
            Thread.CurrentThread.CurrentUICulture = culture;
        }
    }
    public static FlowDirection GetFlowDirection()
    {
        if (_rightToLeftLanguages.ContainsKey(LCID))
        {
            return FlowDirection.RightToLeft;
        }
        return FlowDirection.LeftToRight;
    }
}

오른쪽에서 왼쪽 방향이 필요한 언어의 경우 FrameworkElement.FlowDirection 속성을 참조하십시오.

XML 웹 리소스

XML 웹 리소스가 일반적으로 사용자에게 표시되지 않는 반면 언어 리소스로 XML 웹 리소스 사용에 설명된 대로 다른 솔루션 구성 요소에 대한 리소스로 지역화된 문자열을 저장하는 데 유용할 수 있습니다.

포함된 레이블

이 방법을 사용하는 솔루션 구성 요소에는 각각 솔루션 구성 요소에 지역화된 텍스트가 포함되어야 합니다.

리본

언어 팩을 설치하면 응용 프로그램 리본은 리본의 모든 기본 텍스트에 대해 지역화된 텍스트를 자동으로 표시합니다. 시스템 레이블은 내부 전용인 ResourceId 특성 값에 정의되어 있습니다. 사용자 고유의 텍스트를 추가할 때 <LocLabels> (RibbonDiffXml) 요소를 사용하여 지원하는 언어에 대해 지역화된 텍스트를 제공해야 합니다.추가 정보:리본에 지역화된 레이블 사용

SiteMap

언어 팩을 설치하면 응용 프로그램 탐색 모음의 기본 텍스트가 지역화된 텍스트를 자동으로 표시합니다. 기본 텍스트를 다시 정의하거나 사용자 고유의 텍스트를 제공하려면 <Titles> (SiteMap) 요소를 사용합니다.Titles 요소에는 솔루션에서 지원하는 모든 언어에 대해 지역화된 텍스트가 포함된 <Title> (SiteMap) 요소가 있어야 합니다. 사용자의 기본 설정 언어에 대해 Title 요소를 사용할 수 없는 경우 조직의 기본 언어에 해당하는 제목이 표시됩니다.

<SubArea> (SiteMap) 요소는 SubArea.Url 특성의 대상 콘텐츠가 사용자의 언어 기본 설정을 인식하고 적절하게 조정할 수 있도록 userlcid 매개 변수를 사용하여 사용자의 언어 기본 설정을 전달할 수 있습니다.추가 정보:사이트 맵을 사용하여 URL에 매개 변수 전달

번역 가져오기 및 내보내기

다음 표의 솔루션 구성 요소에 대한 지역화 가능한 레이블은 지역화를 위해 내보낼 수 있습니다.

엔터티

특성

관계

전역 옵션 집합

엔터티 메시지

엔터티 양식

엔터티 보기(SavedQuery)

차트

대시보드

레이블 및 표시 문자열 번역

기본 언어를 사용하여 응용 프로그램에서 사용자 지정만 수행할 수 있습니다. 따라서 지역화된 레이블을 제공하고 이러한 사용자 지정에 대한 문자열을 표시하려는 경우 조직에 활성화된 다른 언어에 대해 지역화할 수 있도록 텍스트의 레이블을 내보내야 합니다. 다음 단계를 수행합니다.

  1. 작업 중인 조직에 번역을 제공하려는 언어에 대해 모든 MUI 팩이 설치되어 있고 언어가 프로비전되어야 합니다.

  2. 솔루션을 만들고 구성 요소를 수정합니다.

  3. 솔루션 개발을 마친 후 "번역 내보내기" 기능을 사용합니다. 그러면 번역이 필요한 모든 레이블이 포함된 Microsoft Office Excel 스프레드시트(CrmTranslations.xml)가 생성됩니다.

  4. 스프레드시트에서 해당 번역을 제공합니다.

  5. "번역 가져오기" 기능을 사용하여 동일한 Microsoft Dynamics 365 조직에 번역을 다시 가져오고 변경 내용을 게시합니다.

  6. 다음에 솔루션을 내보내면 제공된 모든 번역을 표시합니다.

솔루션을 가져올 때 대상 시스템에서 사용할 수 없는 언어에 대한 레이블은 표시되지 않고 경고가 기록됩니다.

대상 시스템의 기본 언어에 대한 레이블이 솔루션 패키지에 제공되지 않을 경우 원본의의 기본 언어의 레이블이 대신 사용됩니다. 예를 들어 영어를 기본 언어로 사용하는 영어 및 프랑스에 대한 레이블이 포함된 솔루션을 가져오지만 대상 시스템에는 일본어를 기본으로 사용하는 일본어 및 프랑스어가 있을 경우 일본어 레이블 대신 영어 레이블이 사용됩니다. 기본 언어 레이블은 null이거나 비어 있을 수 없습니다.

번역 내보내기

번역을 내보내기 전에 먼저 언어 팩을 설치하고 지역화된 모든 언어를 프로비전합니다. 응용 프로그램에서 또는 ExportTranslationRequest 메시지를 사용하여 변역을 내보낼 수 있습니다. 자세한 내용은 도움말 및 교육: 번역을 위해 사용자 지정 엔터티 및 필드 텍스트 내보내기를 참조하십시오.

텍스트 번역

Excel에서 CrmTranslations.xml 파일을 열면 다음 표에 나와 있는 워크시트 3개가 표시됩니다.

워크시트

설명

정보

레이블과 문자열을 내보낸 조직 및 솔루션에 대한 정보를 표시합니다.

표시 문자열

메타데이터 구성 요소에 연결된 메시지의 텍스트를 나타내는 문자열을 표시합니다. 이 표에는 오류 메시지 및 시스템 리본 요소에 사용되는 문자열이 포함됩니다.

지역화된 레이블

모든 메타데이터 구성 요소 레이블에 대한 텍스트를 모두 표시합니다.

언어 전문가, 번역 대행사 또는 로컬라이제이션 업체에 이 파일을 보낼 수 있습니다. 빈 셀에 지역화된 문자열을 제공해야 합니다.

참고

사용자 지정 엔터티의 경우 만든 날짜 또는 만든 사람과 같이 시스템 엔터티를 공유하는 일반적인 레이블이 있습니다. 이미 언어를 설치하고 프로비전했으므로 기본 솔루션에 대한 언어를 내보낼 경우 사용자 지정 엔터티의 일부 레이블을 다른 엔터티에 사용된 동일한 레이블의 지역화된 텍스트와 일치시킬 수 있습니다. 따라서 지역화 비용이 줄어들고 일관성을 유지할 수 있습니다.

워크시트의 텍스트가 번역된 후 CrmTranslations.xml 및 [Content_Types].xml 파일을 하나의 압축 .zip 파일에 추가합니다. 이제 이 파일을 가져올 수 있습니다.

내보낸 파일을 XML 문서로 프로그래밍 방식으로 작업하려는 경우 이러한 파일에서 사용할 스키마에 대한 자세한 내용은 Office 2003 XML 참조 스키마를 참조하십시오.

번역된 텍스트 가져오기

중요

번역된 텍스트만 내보낸 것과 동일한 조직으로 다시 가져올 수 있습니다.

사용자 지정된 엔터티 또는 특성 텍스트를 내보내 번역한 후에는 ImportTranslationRequest 메시지를 사용하여 웹 응용 프로그램에서 번역된 텍스트 문자열을 가져올 수 있습니다. 가져올 파일은 루트에서 CrmTranslations.xml 및 [Content_Types].xml 파일이 포함된 압축 파일이어야 합니다. 자세한 내용은 도움말 및 교육: 번역된 엔터티 및 필드 텍스트 가져오기를 참조하십시오.

완료된 번역을 가져오면 사용자 지정된 텍스트는 번역에 사용된 언어로 작업 중인 사용자에게 표시됩니다.

참고

Microsoft Dynamics 365에서는 변환된 텍스트가 500자를 초과하면 가져올 수 없습니다. 번역 파일에 500자를 초과하는 항목이 있으면 가져오기 프로세스에 실패합니다. 가져오기 프로세스가 실패하면 파일에서 오류의 원인이 된 줄을 검토하고 문자 수를 줄인 다음 가져오기를 다시 시도하십시오.

사용자 지정은 기본 언어에서만 지원되므로 언어 기본 설정으로 설정된 기본 언어를 사용하여 Microsoft Dynamics 365에서 작업합니다. 번역된 텍스트가 표시되는지 확인하려면 Microsoft Dynamics 365 사용자 인터페이스의 언어 기본 설정을 변경해야 합니다. 사용자 지정 작업을 추가로 수행하려면 기본 언어로 되돌려야 합니다.

기본 언어 문자열 지역화

일부 솔루션 구성 요소는 다국어를 지원하지 않습니다. 이러한 구성 요소에는 특정 언어에서만 의미 있을 수 있는 이름 또는 텍스트가 포함됩니다. 특정 언어에 대한 솔루션을 만드는 경우 원하는 조직의 기본 언어에 대해 이러한 솔루션 구성 요소를 정의합니다.

다국어를 지원해야 할 경우 한 가지 방법은 기본 언어 문자열 안에 지역화를 포함하는 것입니다. 예를 들어 "Friend"라는 연결 역할이 있고 영어, 스페인어 및 독일어를 지원해야 할 경우 텍스트 "Friend(Amigo/Freund)"를 연결 역할의 이름으로 사용할 수 있습니다. 텍스트의 길이 문제로 인해 이 방법을 사용하여 지원할 수 있는 언어 개수에 제한이 있습니다.

이 그룹의 일부 솔루션 구성 요소는 관리자에게만 표시됩니다. 시스템의 사용자 지정은 조직의 기본 언어에서만 수행될 수 있으므로 다국어 버전을 제공할 필요는 없습니다.보안 역할필드 보안 프로필 구성 요소는 이 그룹에 속합니다.

계약 템플릿은 서비스 계약 유형에 대한 설명을 제공합니다.이름약어 필드에 텍스트를 입력해야 합니다. 고유하고 조직의 모든 사용자에게 적절한 이름과 약어를 사용하는 것이 좋습니다.

연결 역할은 설명하는 연결 역할 범주와 이름을 선택하는 사용자에 따라 달라집니다. 연결 역할은 비교적 짧기 때문에 기본 언어 문자열로 지역화를 포함하는 것이 좋습니다.

이벤트에 대해 시작되는 **프로세스(워크플로)**는 지역화되는 텍스트로 레코드를 업데이트할 필요가 없는 한 잘 작동할 수 있습니다. 지역화된 텍스트에 적용할 수 있는 논리가 플러그 인 어셈블리와 같은 전략을 사용할 수 있도록 워크플로 어셈블리를 사용할 수 있습니다(언어 리소스로 XML 웹 리소스 사용).

사람들이 선택할 수 있도록 주문형 워크플로에는 이름이 필요합니다. 주문형 워크플로의 이름에 지역화를 포함하는 것 외 다른 방법은 지역화된 이름을 사용하여 동일한 하위 프로세스를 각각 호출하는 여러 워크플로를 만드는 것입니다. 하지만 모든 사용자에게 기본 설정된 사용자 인터페이스 언어뿐 아니라 주문형 워크플로의 전체 목록이 표시됩니다.

지역화 필요 없음

SDK 메시지 처리 단계서비스 끝점 솔루션 구성 요소는 지역화할 수 있는 텍스트를 사용자에게 표시하지 않습니다. 이러한 구성 요소에 조직의 기본 언어에 해당하는 이름과 설명이 있어야 할 경우 해당 언어로 이름과 설명을 사용하는 관리형 솔루션을 만들고 내보낼 수 있습니다.

각 언어에 대한 별도 구성 요소

다음 솔루션 구성 요소에는 상당한 양의 지역화된 텍스트를 포함할 수 있습니다.

  • 문서 템플릿

  • 전자 메일 템플릿

  • 편지 병합 템플릿

  • 보고서

  • 대화

이러한 유형의 솔루션 구성 요소의 경우 권장되는 방법은 각 언어에 대해 별도의 구성 요소를 만드는 것입니다. 즉, 일반적으로 핵심 솔루션 구성 요소가 포함된 기본 관리형 솔루션을 만든 후 각 언어에 대해 이러한 솔루션 구성 요소가 포함된 별도의 관리형 솔루션을 만듭니다. 고객이 기본 솔루션을 설치한 후 조직에 프로비전한 언어에 대해 관리형 솔루션을 설치할 수 있습니다.

**프로세스(워크플로)**와 달리 사용자의 현재 언어 기본 설정을 반영하여 해당 언어의 사용자에게만 대화를 표시하는 대화를 만들 수 있습니다.

지역화된 대화 상자 만들기

  1. 적절한 언어 팩을 설치하고 언어를 프로비전합니다.

    자세한 내용은 TechNet: 언어 팩 설치 지침을 참조하십시오.

  2. 대화에 사용하려는 언어에 대해 사용자 인터페이스 언어를 지정하기 위해 개인 옵션을 변경합니다.

  3. 설정으로 이동하고 프로세스 센터 그룹에서 프로세스를 선택합니다.

  4. 새로 만들기를 클릭하고 지정한 언어로 대화 상자를 만듭니다.

  5. 대화 상자를 만든 후 개인 옵션을 변경하여 조직의 기본 언어를 지정합니다.

  6. 조직의 기본 언어를 사용할 경우 솔루션 영역으로 이동하여 설정에서 지역화된 대화 상자를 솔루션의 일부로 추가합니다.

다른 언어로 만든 대화 상자는 해당 언어를 사용하여 Microsoft Dynamics 365을 보는 사용자에게만 표시됩니다.

언어 리소스로 XML 웹 리소스 사용

플러그 인 어셈블리 솔루션 구성 요소는 레코드를 만들고 업데이트할 뿐만 아니라 InvalidPluginExecutionException을 발생하여 최종 사용자에게 메시지를 보낼 수 있습니다. Silverlight 웹 리소스와는 달리 플러그 인은 리소스 파일을 사용할 수 없습니다.

플러그 인에 지역화된 텍스트가 필요할 경우 플러그 인에서 필요할 때 액세스할 수 있도록 XML 웹 리소스를 사용하여 지역화된 문자열을 저장할 수 있습니다. XML의 구조는 옵션이지만 ASP.NET 리소스(resx)에 사용되는 구조를 따라 각 언어에 대해 별도의 XML 웹 리소스를 만들 수 있습니다. 예를 들어 다음은 localizedString.en_US라는 XML 웹 리소스로,resx 파일에 사용된 패턴을 따릅니다.

<root>
 <data name="ErrorMessage">
  <value>There was an error completing this action. Please try again.</value>
 </data>
 <data name="Welcome">
  <value>Welcome</value>
 </data>
</root>

다음 코드에서는 사용자에게 메시지를 표시하기 위해 플러그 인에 지역화된 메시지를 전달할 수 있는 방법을 보여 줍니다. 이 코드는 Account 엔터티에 대한 Delete 이벤트의 사전 유효성 검사 스테이지입니다.

protected void ExecutePreValidateAccountDelete(LocalPluginContext localContext)
  {
   if (localContext == null)
   {
    throw new ArgumentNullException("localContext");
   }
   int OrgLanguage = RetrieveOrganizationBaseLanguageCode(localContext.OrganizationService);
   int UserLanguage = RetrieveUserUILanguageCode(localContext.OrganizationService,
 localContext.PluginExecutionContext.InitiatingUserId);
   String fallBackResourceFile = "";
   switch (OrgLanguage)
   {
    case 1033:
     fallBackResourceFile = "new_localizedStrings.en_US";
     break;
    case 1041:
     fallBackResourceFile = "new_localizedStrings.ja_JP";
     break;
    case 1031:
     fallBackResourceFile = "new_localizedStrings.de_DE";
     break;
    case 1036:
     fallBackResourceFile = "new_localizedStrings.fr_FR";
     break;
    case 1034:
     fallBackResourceFile = "new_localizedStrings.es_ES";
     break;
    case 1049:
     fallBackResourceFile = "new_localizedStrings.ru_RU";
     break;
    default:
     fallBackResourceFile = "new_localizedStrings.en_US";
     break;
   }
   String ResourceFile = "";
   switch (UserLanguage)
   {
    case 1033:
     ResourceFile = "new_localizedStrings.en_US";
     break;
    case 1041:
     ResourceFile = "new_localizedStrings.ja_JP";
     break;
    case 1031:
     ResourceFile = "new_localizedStrings.de_DE";
     break;
    case 1036:
     ResourceFile = "new_localizedStrings.fr_FR";
     break;
    case 1034:
     ResourceFile = "new_localizedStrings.es_ES";
     break;
    case 1049:
     ResourceFile = "new_localizedStrings.ru_RU";
     break;
    default:
     ResourceFile = fallBackResourceFile;
     break;
   }
   XmlDocument messages = RetrieveXmlWebResourceByName(localContext, ResourceFile);
   String message = RetrieveLocalizedStringFromWebResource(localContext, messages, "ErrorMessage");
   throw new InvalidPluginExecutionException(message);
  }
  protected static int RetrieveOrganizationBaseLanguageCode(IOrganizationService service)
  {
   QueryExpression organizationEntityQuery = new QueryExpression("organization");
   organizationEntityQuery.ColumnSet.AddColumn("languagecode");
   EntityCollection organizationEntities = service.RetrieveMultiple(organizationEntityQuery);
   return (int)organizationEntities[0].Attributes["languagecode"];
  }
  protected static int RetrieveUserUILanguageCode(IOrganizationService service, Guid userId)
  {
   QueryExpression userSettingsQuery = new QueryExpression("usersettings");
   userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
   userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);
   EntityCollection userSettings = service.RetrieveMultiple(userSettingsQuery);
   if (userSettings.Entities.Count > 0)
   {
    return (int)userSettings.Entities[0]["uilanguageid"];
   }
   return 0;
  }
  protected static XmlDocument RetrieveXmlWebResourceByName(LocalPluginContext context, string webresourceSchemaName)
  {
   context.TracingService.Trace("Begin:RetrieveXmlWebResourceByName, webresourceSchemaName={0}", webresourceSchemaName);
   QueryExpression webresourceQuery = new QueryExpression("webresource");
   webresourceQuery.ColumnSet.AddColumn("content");
   webresourceQuery.Criteria.AddCondition("name", ConditionOperator.Equal, webresourceSchemaName);
   EntityCollection webresources = context.OrganizationService.RetrieveMultiple(webresourceQuery);
   context.TracingService.Trace("Webresources Returned from server. Count={0}", webresources.Entities.Count);
   if (webresources.Entities.Count > 0)
   {
    byte[] bytes = Convert.FromBase64String((string)webresources.Entities[0]["content"]);
    // The bytes would contain the ByteOrderMask. Encoding.UTF8.GetString() does not remove the BOM.
    // Stream Reader auto detects the BOM and removes it on the text
    XmlDocument document = new XmlDocument();
    document.XmlResolver = null;
    using (MemoryStream ms = new MemoryStream(bytes))
    {
     using (StreamReader sr = new StreamReader(ms))
     {
      document.Load(sr);
     }
    }
    context.TracingService.Trace("End:RetrieveXmlWebResourceByName , webresourceSchemaName={0}", webresourceSchemaName);
    return document;
   }
   else
   {
    context.TracingService.Trace("{0} Webresource missing. Reinstall the solution", webresourceSchemaName);
    throw new InvalidPluginExecutionException(String.Format("Unable to locate the web resource {0}.", webresourceSchemaName));
    return null;
 // This line never reached
   }
  }
  protected static string RetrieveLocalizedStringFromWebResource(LocalPluginContext context, XmlDocument resource, string resourceId)
  {
   XmlNode valueNode = resource.SelectSingleNode(string.Format(CultureInfo.InvariantCulture, "./root/data[@name='{0}']/value", resourceId));
   if (valueNode != null)
   {
    return valueNode.InnerText;
   }
   else
   {
    context.TracingService.Trace("No Node Found for {0} ", resourceId);
    throw new InvalidPluginExecutionException(String.Format("ResourceID {0} was not found.", resourceId));
   }
  }

참고 항목

솔루션을 사용하여 확장 패키지 및 배포
솔루션 소개
솔루션 개발 계획
솔루션 구성 요소에 대해 종속성 추적
비관리형 솔루션 만들기, 내보내기 또는 가져오기
관리형 솔루션 만들기, 설치 및 업데이트
솔루션 제거 또는 삭제
솔루션 엔터티
제품 속성 값 지역화

Microsoft Dynamics 365

© 2017 Microsoft. All rights reserved. 저작권 정보