Supportare la codifica dei caratteri non Unicode in App per la logica di Azure

Si applica a: App per la logica di Azure (consumo + Standard)

Quando si utilizzano payload di testo, App per la logica di Azure inferisce che il testo viene codificato in un formato Unicode, ad esempio UTF-8. Potrebbero verificarsi problemi durante la ricezione, l'invio o l'elaborazione di caratteri con codifica diverse nel flusso di lavoro. Ad esempio, è possibile ottenere caratteri danneggiati nei file flat quando si utilizzano sistemi legacy che non supportano Unicode.

Per usare il testo con altre codifica dei caratteri, applicare la codifica base64 al payload non Unicode. Questo passaggio impedisce alle app per la logica di presumere che il testo sia in formato UTF-8. È quindi possibile convertire qualsiasi oggetto . Codifica supportata da NET a UTF-8 usando Funzioni di Azure.

Questa soluzione funziona con flussi di lavoro multi-tenant e single-tenant . È anche possibile usare questa soluzione con il connettore AS2.

Convertire la codifica del payload

Verificare innanzitutto che il trigger possa identificare correttamente il tipo di contenuto. Questo passaggio garantisce che app per la logica non presuppone più che il testo sia UTF-8.

Nei trigger e nelle azioni con la proprietà Inferi tipo di contenuto selezionare No. In genere, è possibile trovare questa proprietà nell'elenco Aggiungi parametri dell'operazione. Tuttavia, se l'operazione non include questa proprietà, il tipo di contenuto viene impostato dal messaggio in ingresso.

L'elenco seguente mostra alcuni connettori in cui è possibile disabilitare automaticamente l'inferenza del tipo di contenuto:

Se si usa il trigger Request per text/plain il contenuto, è necessario impostare il charset parametro che si trova nell'intestazione della Content-Type chiamata. In caso contrario, i caratteri potrebbero essere danneggiati oppure il parametro non corrisponde al formato di codifica del payload. Per altre informazioni, vedere come gestire il text/plain tipo di contenuto.

Ad esempio, il trigger HTTP converte il contenuto in ingresso in UTF-8 quando l'intestazione viene impostata con il Content-Type parametro corretto charset :

{
    "headers": {
        <...>
        "Content-Type": "text/plain; charset=windows-1250"
        },
        "body": "non UTF-8 text content"
}

Se si imposta l'intestazione Content-Type su application/octet-stream, è anche possibile ricevere caratteri che non sono UTF-8. Per altre informazioni, vedere come gestire il application/octet-stream tipo di contenuto.

Contenuto di codifica Base64

Prima di codificare il contenuto in una stringa, assicurarsi di convertire il testo in UTF-8. In caso contrario, i caratteri potrebbero restituire danneggiati.

Eseguire quindi la conversione di qualsiasi oggetto . Codifica supportata da NET in un altro oggetto . Codifica supportata da NET. Esaminare l'esempio di codice Funzioni di Azure o l'esempio di codice .NET:

Suggerimento

Per le app per la logica a tenant singolo , è possibile migliorare le prestazioni e ridurre la latenza eseguendo localmente la funzione di conversione.

Funzioni di Azure versione

L'esempio seguente è per Funzioni di Azure versione 2:

using System;
using System.IO;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;

public static class ConversionFunctionv2 {
  [FunctionName("ConversionFunctionv2")]
  public static IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, TraceWriter log) {
    log.Info("C# HTTP trigger function processing a request.");

    Encoding inputEncoding = null;

    string requestBody = new StreamReader(req.Body).ReadToEnd();
    dynamic data = JsonConvert.DeserializeObject(requestBody);

    if (data == null || data.text == null || data.encodingInput == null || data.encodingOutput == null) {
      return new BadRequestObjectResult("Please pass text/encodingOutput properties in the input JSON object.");
    }

    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

    try {
      string encodingInput = data.encodingInput.Value;
      inputEncoding = Encoding.GetEncoding(name: encodingInput);
    } catch (ArgumentException) {
      return new BadRequestObjectResult($"Input character set value '{data.encodingInput.Value}' is not supported. Supported values are listed at https://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx.");
    }

    Encoding encodingOutput = null;
    try {
      string outputEncoding = data.encodingOutput.Value;
      encodingOutput = Encoding.GetEncoding(outputEncoding);
    } catch (ArgumentException) {
      return new BadRequestObjectResult($"Output character set value '{data.encodingOutput.Value}' is not supported. Supported values are listed at https://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx.");
    }

    return (ActionResult) new JsonResult(
      value: new {
        text = Convert.ToBase64String(
          Encoding.Convert(
            srcEncoding: inputEncoding,
            dstEncoding: encodingOutput,
            bytes: Convert.FromBase64String((string) data.text)))
      });
  }
}

Versione di .NET

L'esempio seguente è per l'uso con .NET Standard e Funzioni di Azure versione 2:

    using System;
    using System.IO;
    using System.Text;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Azure.WebJobs.Host;
    using Newtonsoft.Json;

    public static class ConversionFunctionNET
    {
        [FunctionName("ConversionFunctionNET")]
        public static IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequest req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processing a request.");

            Encoding inputEncoding = null;

            string requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data = JsonConvert.DeserializeObject(requestBody);

            if (data == null || data.text == null || data.encodingInput == null || data.encodingOutput == null)
            {
                return new BadRequestObjectResult("Please pass text/encodingOutput properties in the input JSON object.");
            }

            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            try
            {
                string encodingInput = data.encodingInput.Value;
                inputEncoding = Encoding.GetEncoding(name: encodingInput);
            }
            catch (ArgumentException)
            {
                return new BadRequestObjectResult($"Input character set value '{data.encodingInput.Value}' is not supported. Supported values are listed at https://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx.");
            }

            Encoding encodingOutput = null;
            try
            {
                string outputEncoding = data.encodingOutput.Value;
                encodingOutput = Encoding.GetEncoding(outputEncoding);
            }
            catch (ArgumentException)
            {
                return new BadRequestObjectResult($"Output character set value '{data.encodingOutput.Value}' is not supported. Supported values are listed at https://msdn.microsoft.com/en-us/library/system.text.encoding(v=vs.110).aspx.");
            }

            return (ActionResult)new JsonResult(
                value: new
                {
                    text = Convert.ToBase64String(
                        Encoding.Convert(
                            srcEncoding: inputEncoding,
                            dstEncoding: encodingOutput,
                            bytes: Convert.FromBase64String((string)data.text)))
                });
        }
    }

Usando questi stessi concetti, è anche possibile inviare un payload non Unicode dal flusso di lavoro.

Conversioni del payload di esempio

In questo esempio la stringa di input di esempio con codifica base64 è un nome personale che contiene caratteri accentati: Héloïse

Input di esempio:

{  
    "text": "SMOpbG/Dr3Nl",
    "encodingInput": "utf-8",
    "encodingOutput": "windows-1252"
}

Output di esempio:

{
    "text": "U01PcGJHL0RyM05s"
}

Inviare payload non Unicode

Se è necessario inviare un payload non Unicode dal flusso di lavoro, eseguire i passaggi per convertire il payload in UTF-8 inverso. Mantenere il testo in UTF-8 il più a lungo possibile all'interno del sistema. Usare quindi la stessa funzione per convertire i caratteri UTF-8 con codifica base64 nella codifica necessaria. Applicare quindi la decodifica base64 al testo e inviare il payload.

Convertire i payload per AS2

È anche possibile usare questa soluzione con payload non Unicode nel connettore AS2 v2. Se non si convertono payload passati a AS2 a UTF-8, è possibile che si verifichino problemi con l'interpretazione del payload. Questi problemi potrebbero causare una mancata corrispondenza con l'hash MIC tra i partner a causa di caratteri non interpretati.

Passaggi successivi