Condividi tramite


Creare soluzioni che supportano più lingue

 

Data di pubblicazione: gennaio 2017

Si applica a: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

Microsoft Dynamics 365 (online e locale) supporta più lingue Se si desidera che la soluzione venga installata per le organizzazioni che includono lingue di base diverse o in cui viene eseguito il provisioning di più lingue, tenere questo in considerazione quando si pianifica la soluzione. Nella tabella seguente sono elencate le tattiche da utilizzare e i componenti della soluzione da includere in una soluzione che supporta più lingue.

Tattica

Tipo di componente di soluzione

Opzione per sviluppatori

Risorse Web

Etichette incorporate

Navigazione applicazione (SiteMap)
Barre multifunzione

Esportare e importare le traduzioni

Attributi
Grafici
Dashboard
Entità
Relazioni entità
Moduli
Messaggi
Set di opzioni
Visualizzazioni

Localizzazione in stringhe della lingua di base

Modelli di contratto
Ruoli di connessione
Processi (Flusso di lavoro)
Ruoli di sicurezza
Profili di sicurezza campi

Localizzazione non necessaria.

Passaggi di elaborazione messaggi SDK
Endpoint servizio

Componente separato per ogni lingua

Modelli di articolo
Modelli di messaggio
Modelli di stampa unione
Report
Interazioni

Utilizzare le risorse Web XML come risorse della lingua

Assembly del plug-in

Le sezioni seguenti contengono ulteriori dettagli per ogni tattica.

Opzione per sviluppatori

Le risorse Web hanno un attributo LanguageCode che può essere impostato nell'interfaccia utente, ma questo valore non è utilizzato dall'applicazione. Poiché le risorse Web sono con indirizzo URL, in genere si accede a una risorsa Web per nome anziché eseguendo una query sulle risorse Web disponibili con LanguageCode come criterio. Pertanto, LanguageCode è di valore limitato. Lo scenario più comune è che sarà necessario individuare la lingua appropriata in base al contesto in cui la risorsa Web viene visualizzata. Per le risorse Web, l'oggetto del contesto consente di accedere alle funzioni getUserLcid e getOrgLcid. Entrambe queste funzioni restituiscono un valore intero che corrisponde all'ID delle impostazioni locali (LCID).Valori LCID (ID impostazioni locali) validi sono disponibili alla pagina Grafico LCID (impostazioni ID locali).

Per le risorse Web che espongono il testo dell'interfaccia utente, è possibile utilizzare qualsiasi metodo desiderato per gestire il modo in cui le preferenze di lingua dell'utente verranno supportate da testo e layout. L'implementazione specifica dipende dal tipo di risorsa Web.

Risorse Web HTML.

Un'opzione consiste nel creare risorse Web localizzate separate che variano a seconda del nome applicato. Ad esempio, è possibile disporre di una risorsa Web denominata new_/my_solution/1033/content.htm per supportare la lingua inglese e una denominata new_/my_solution/1041/content.htm per supportare il giapponese. Per le lingue che richiedono la direzione da destra a sinistra, vedere Procedura: Visualizzare il testo da destra a sinistra utilizzando i tag HTML per la globalizzazione.

Se si desidera impostare in modo dinamico il testo dell'interfaccia utente in base alla lingua di un utente, è possibile archiviare tutti i valori della stringa localizzata in un oggetto definito in un file risorsa Web script. A seconda della preferenza di lingua dell'utente, è possibile impostare gli elementi di testo dell'interfaccia utente utilizzando le stringhe archiviate nell'oggetto quando viene caricata la pagina. Il seguente esempio di codice di JavaScript mostra un metodo per impostare le stringhe localizzate.

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];

Risorse Web Silverlight

Le applicazioni diSilverlight possono essere scritte per supportare le risorse delle lingue localizzate.Ulteriori informazioni:Localizzazione delle applicazioni basate su Silverlight.

La classe seguente consente di accedere alla preferenza di lingua dell'utente in base al contesto in cui viene presentata la risorsa Web Silverlight. Questa classe supporta l'inglese Stati Uniti, l'arabo, il tedesco, l'ebraico e il giapponese. Deve essere modificata per le lingue specifiche supportate dalla risorsa Web 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;
    }
}

Per le lingue che richiedono la direzione da destra a sinistra, vedere Proprietà FrameworkElement.FlowDirection.

Risorse Web XML

Sebbene le risorse Web XML in genere non vengano visualizzate per gli utenti, possono essere utili per archiviare le stringhe localizzate come risorse per altri componenti di soluzione come descritto in Utilizzare le risorse Web XML come risorse della lingua.

Etichette incorporate

Ognuno dei componenti di soluzione che utilizza questa tattica richiede l'inclusione del testo localizzato nel componente di soluzione.

Barre multifunzione

Quando viene installato un Language Pack, la barra multifunzione dell'applicazione visualizza automaticamente il testo localizzato per tutto il testo predefinito nella barra multifunzione. Le etichette di sistema vengono definite in un valore dell'attributo ResourceId che è solo per uso interno. Quando si aggiunge un testo personalizzato, è necessario utilizzare l'elemento <LocLabels> (RibbonDiffXml) per specificare il testo localizzato per le lingue supportate.Ulteriori informazioni:Utilizzo delle etichette localizzate con le barre multifunzione

SiteMap

Quando viene installato un Language Pack, nella barra di navigazione dell'applicazione il testo predefinito viene visualizzato automaticamente come localizzato. Per sostituire il testo predefinito o per rendere personale il testo, utilizzare l'elemento <Titles> (SiteMap). L'elemento Titles deve contenere un elemento <Title> (SiteMap) che contiene testo localizzato per tutte le lingue supportate dalla soluzione. Se un elemento Title non è disponibile per la lingua preferita dell'utente, viene visualizzato il titolo corrispondente alla lingua di base dell'organizzazione.

L'elemento <SubArea> (SiteMap) consente di cambiare la preferenza di lingua dell'utente utilizzando il parametro userlcid in modo che il contenuto che costituisce la destinazione dell'attributo SubArea.Url possa tener conto della preferenza di lingua dell'utente e regolarsi di conseguenza.Ulteriori informazioni:Passare i parametri a un URL tramite SiteMap

Esportare e importare le traduzioni

Le etichette localizzabili per i componenti di soluzione nella seguente tabella possono essere esportate per la localizzazione.

Entità

Attributi

Relazioni

Set di opzioni globale

Messaggi entità

Moduli delle entità

Visualizzazioni delle entità (SavedQuery)

Grafici

Dashboard

Traduzione di etichette e stringhe visualizzate

Le personalizzazioni possono essere eseguite solo nell'applicazione utilizzando la lingua di base. Pertanto, se si desidera fornire le etichette localizzate e le stringhe visualizzate per queste personalizzazioni, è necessario esportare il testo delle etichette in modo da poterle localizzare per tutte le altre lingue abilitate per l'organizzazione. Utilizzare i passaggi seguenti:

  1. Verificare che nell'organizzazione che si sta utilizzando siano installati tutti i MUI Pack e sia stato eseguito il provisioning delle lingue per cui si desidera fornire delle traduzioni.

  2. Creare una soluzione e modificare i componenti.

  3. Dopo aver completato lo sviluppo della soluzione utilizzare la funzionalità "Esporta traduzioni". Verrà generato un foglio di calcolo Microsoft Office Excel (CrmTranslations.xml) contenente tutte le etichette da tradurre.

  4. Nel foglio di calcolo, fornire le traduzioni corrispondenti.

  5. Importare le traduzioni nuovamente nella stessa organizzazione Microsoft Dynamics 365 utilizzando la funzionalità "Importa traduzioni" e pubblicare le modifiche.

  6. Alla successiva esportazione la soluzione conterrà tutte le traduzioni fornite.

Quando viene importata una soluzione, le etichette per le lingue non disponibili nel sistema di destinazione vengono rimosse e viene registrato un avviso.

Se le etichette per la lingua di base del sistema di destinazione non sono disponibili nel pacchetto della soluzione, vengono in alternativa utilizzate le etichette della lingua di base dell'origine. Ad esempio, se si importa una soluzione che contiene le etichette per l'inglese e il francese con l'inglese come lingua di base, ma il sistema di destinazione ha il giapponese e il francese con il giapponese come lingua di base, vengono utilizzate le etichette inglesi anziché quelle giapponesi. le etichette della lingua di base non possono essere null o vuote.

Esportazione delle traduzioni

Prima di esportare le traduzioni è innanzitutto necessario installare i Language Pack ed eseguire il provisioning di tutte le lingue che si desidera localizzare. È possibile esportare le traduzioni nell'applicazione Web o utilizzando messaggio di ExportTranslationRequest. Per ulteriori informazioni, vedere Guida e formazione: Esportare entità e testo dei campi personalizzati per la traduzione.

Traduzione del testo

Quando si apre il file CrmTranslations.xml in Excel verranno visualizzati i tre fogli di lavoro elencati nella tabella seguente.

Foglio di lavoro

Descrizione

Informazioni

Visualizza le informazioni sull'organizzazione e la soluzione da cui sono state esportate le etichette e le stringhe.

Stringhe visualizzate

Stringhe visualizzate che rappresentano il testo di tutti i messaggi associati a un componente di metadati. In questa tabella vengono inclusi i messaggi di errore e le stringhe utilizzate per gli elementi della barra multifunzione del sistema.

Etichette localizzate

Visualizza tutto il testo per tutte le etichette dei componenti di metadati.

È possibile inviare questo file a un traduttore esperto, a un'agenzia di traduzione o a una società di localizzazione. Dovranno fornire le stringhe localizzate per tutte le celle vuote.

Nota

Per le entità personalizzate esistono alcune etichette comuni condivise con le entità di sistema, come Data creazione o Autore. Poiché le lingue sono già state installate e ne è stato già eseguito il provisioning, se si esportano le lingue per la soluzione predefinita è possibile abbinare alcune etichette nelle entità personalizzate al testo localizzato per le etichette identiche utilizzate da altre entità. In questo modo è possibile ridurre i costi di localizzazione e migliorare la coerenza.

Dopo che il testo nei fogli di lavoro è stato localizzato, aggiungere sia i file [Content_Types].xml che CrmTranslations.xml in un singolo file .zip compresso, che potrà ora essere importato.

Se si preferisce utilizzare i file esportati a livello di programmazione come un documento XML, vedere Schemi di riferimento di Office 2003 XML per informazioni sugli schemi utilizzati da tali file.

Importazione del testo tradotto

Importante

È possibile importare solo testo tradotto nuovamente nella stessa organizzazione da cui è stato esportato.

Dopo avere esportato e tradotto il testo degli attributi e delle entità personalizzate è possibile importare le stringhe di testo tradotte nell'applicazione Web utilizzando il messaggio ImportTranslationRequest. Il file importato deve essere un file compresso contenente CrmTranslations.xml e il file [Content_Types].xml al livello radice. Per ulteriori informazioni, vedere Guida e formazione: Importare testo tradotto per entità e campi.

Al termine dell'importazione, il testo personalizzato verrà visualizzato per gli utenti che lavorano nelle lingue per cui sono disponibili traduzioni.

Nota

Microsoft Dynamics 365 non supporta l'importazione di testo tradotto con una lunghezza maggiore di 500 caratteri. Il processo di importazione ha esito negativo se il file delle traduzioni include elementi più lunghi di 500 caratteri. In caso di esito negativo del processo di importazione, controllare la riga del file che ha causato l'errore, ridurre il numero di caratteri e riprovare l'importazione.

Dato che la personalizzazione è supportata solo nella lingua di base, è possibile che si lavori in Microsoft Dynamics 365 con la lingua di base impostata come preferenza per la lingua. Per verificare che il testo tradotto venga visualizzato, modificare la preferenza per la lingua dell'interfaccia utente di Microsoft Dynamics 365. Per eseguire ulteriori personalizzazioni, tornare alla lingua di base.

Localizzazione in stringhe della lingua di base

Alcuni componenti di soluzione non supportano più lingue. Questi componenti includono nomi o testo che possono essere significativi solo in una lingua specifica. Se si crea una soluzione per una lingua specifica, definire questi componenti della soluzione per la lingua di base desiderata per l'organizzazione.

Se è necessario supportare più lingue, una tattica consiste nell'includere la localizzazione nelle stringhe della lingua di base. Ad esempio, se di dispone di un ruolo di connessione denominato "Amico" ed è necessario supportare l'inglese, lo spagnolo e il tedesco, è possibile utilizzare il testo "Amico (Amigo/Freund)" come nome per il ruolo di connessione. A causa di problemi legati alla lunghezza del testo esistono limitazioni relative al numero di lingue supportate con questa tattica.

Alcuni componenti di soluzione del gruppo sono visibili solo per gli amministratori. Dato che la personalizzazione del sistema può essere eseguita solo nella lingua di base dell'organizzazione non è necessario fornire più versioni di lingue. I componenti Ruoli di sicurezza e Profilo sicurezza campi appartengono al gruppo.

Modelli di contratto fornisce una descrizione di un tipo di contratto di servizio. Questi richiedono testo per i campi Nome e Abbreviazione. È necessario considerare l'utilizzo di nomi e abbreviazioni univoci e appropriati per tutti gli utenti dell'organizzazione.

Ruoli di connessione si basano su una persona che seleziona categorie e nomi del ruolo di connessione descrittivi. Poiché questi possono essere relativamente brevi, è consigliabile includere la localizzazione nelle stringhe della lingua di base.

Processi (flusso di lavoro) che vengono avviati per gli eventi possono essere compatibili fino a quando l'utente non deve aggiornare i record col testo che deve essere localizzato. È possibile utilizzare un assembly del flusso di lavoro in modo che la logica che può essere applicata al testo localizzato possa utilizzare la stessa strategia degli assembly del plug-in (Utilizzare le risorse Web XML come risorse della lingua.

Flussi di lavoro su richiesta richiedono un nome perché possano essere selezionati dagli utenti. Oltre a includere la localizzazione nel nome del flusso di lavoro su richiesta, un'altra tattica è creare più flussi di lavoro con nomi localizzati che chiamino ciascuno lo stesso processo figlio. Tuttavia, tutti gli utenti visualizzeranno l'elenco completo dei flussi di lavoro su richiesta, non solo quelli nella lingua preferita l'interfaccia utente.

Localizzazione non necessaria.

I componenti della soluzione Passaggio di elaborazione messaggi SDK e Endpoint servizio non espongono il testo localizzabile per gli utenti. Se è importante che questi componenti includano nomi e descrizioni corrispondenti alla lingua di base dell'organizzazione, è possibile creare ed esportare una soluzione gestita con i nomi e le descrizioni in tale lingua.

Componente separato per ogni lingua

I componenti di soluzione seguenti possono contenere ciascuno una quantità considerevole di testo da localizzare:

  • Modelli di articolo

  • Modelli di messaggio

  • Modelli di stampa unione

  • Report

  • Interazioni

Per questi tipi di componenti della soluzione, la tattica consigliata consiste nel creare componenti separati per ogni lingua. Questo significa che normalmente si crea una soluzione gestita di base che contiene i componenti di soluzione di base e quindi una soluzione gestita separata che contiene questi componenti di soluzione per ogni lingua. Dopo che i clienti installano la soluzione di base, è possibile installare le soluzioni gestite per le lingue di cui hanno eseguito il provisioning per l'organizzazione.

A differenza di Processi (flusso di lavoro), è possibile creare Interazioni che rifletteranno le impostazioni correnti di preferenza per la lingua dell'utente e visualizzeranno le interazioni solo per gli utenti di tale lingua.

Creare una finestra di dialogo localizzata

  1. Installare il Language Pack appropriato ed eseguire il provisioning della lingua.

    Per ulteriori informazioni, vedere TechNet: Istruzioni per l'installazione del Language Pack.

  2. Modificare le opzioni personali per specificare la Lingua interfaccia utente per la lingua desiderata per l'interazione.

  3. Passare a Impostazioni e nel gruppo Centro processi selezionare Processi.

  4. Fare clic su Nuovo e creare l'interazione nella lingua specificata.

  5. Dopo aver creato l'interazione, modificare le opzioni personali per specificare la lingua di base dell'organizzazione.

  6. Quando si utilizza la lingua di base dell'organizzazione è possibile passare all'area Soluzioni in Impostazioni e aggiungere l'interazione localizzata come parte di una soluzione.

L'interazione creata nell'altra lingua verrà visualizzata solo per gli utenti che visualizzano Microsoft Dynamics 365 tramite tale lingua.

Utilizzare le risorse Web XML come risorse della lingua

I componenti di soluzione dell'assembly del plug-in possono inviare messaggi a un utente finale generando un InvalidPluginExecutionException, nonché creando e aggiornando i record. A differenza della risorsa Web Silverlight, i plug-in non possono utilizzare i file di risorse.

Se un plug-in richiede testo localizzato, è possibile utilizzare una risorsa Web XML per archiviare le stringhe localizzate in modo che il plug-in possa accedere a esse quando necessario. È possibile scegliere la struttura del codice XML, ma è consigliabile seguire la struttura utilizzata dai file di risorse ASP.NET (.resx) per creare risorse Web XML separate per ogni lingua. Ad esempio, la seguenti è una risorsa Web XML denominata localizedString.en_US che segue il modello utilizzato dai file .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>

Nel seguente codice viene illustrato come è possibile passare nuovamente in un plug-in un messaggio localizzato per visualizzare un messaggio per un utente. Riguarda la fase di convalida preliminare di un evento Delete per l'entità Account :

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));
   }
  }

Vedere anche

Comprimere e distribuire estensioni con soluzioni
Introduzione alle soluzioni
Pianificare per lo sviluppo di soluzioni
Traccia delle dipendenze dei componenti di soluzione
Creare, esportare o importare una soluzione non gestita
Creare, installare e aggiornare una soluzione gestita
Disinstallare o eliminare una soluzione
Entità soluzione
Localizzare i valori delle proprietà del prodotto

Microsoft Dynamics 365

© 2017 Microsoft. Tutti i diritti sono riservati. Copyright