在 Azure Logic Apps 中支援非 Unicode 字元編碼

適用於:Azure Logic Apps (使用量 + 標準)

當您使用文字承載時,Azure Logic Apps 會推斷文字的編碼格式為 Unicode,例如 UTF-8。 您在工作流程中可能會無法收到、傳送或處理使用不同編碼的字元。 例如,使用不支援 Unicode 的舊版系統時,您可能會在一般檔案中發現損毀的字元。

若要使用具有其他字元編碼的文字,請將 base64 編碼套用至非 Unicode 承載。 此步驟可防止 Logic Apps 假設文字採用 UTF-8 格式。 然後,您可以使用 Azure Functions 將 .NET 支援的編碼轉換為 UTF-8。

此解決方案適用於多租用戶單一租用戶工作流程。 您也可以搭配 AS2 連接器使用此解決方案

轉換承載編碼

首先,檢查您的觸發程序是否可以正確識別內容類型。 此步驟可確保 Logic Apps 不再假設文字為 UTF-8。

在具有 [推斷內容類型] 屬性的觸發程序和動作中,選取 [否]。 您通常可以在作業的 [新增參數] 清單中找到這個屬性。 不過,如果作業不包含這個屬性,則會由輸入訊息設定內容類型。

下列清單顯示一些連接器,您可以在其中停用自動推斷內容類型:

如果您針對 text/plain 內容使用要求觸發程序,就必須設定位於呼叫的 Content-Type 標頭中的 charset 參數。 否則,字元可能會損毀,或參數不符合承載的編碼格式。 如需詳細資訊,請檢閱如何處理 text/plain 內容類型

例如,當您使用正確的 charset 參數設定 Content-Type 標頭時,HTTP 觸發程序會將傳入內容轉換為 UTF-8:

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

如果您將 Content-Type 標頭設定為 application/octet-stream,則也可能會收到不是 UTF-8 的字元。 如需詳細資訊,請參閱如何處理 application/octet-stream 內容類型

Base64 編碼內容

進行 base64 編碼使內容成為字串前,請確定您已將文字轉換為 UTF-8。 否則,傳回的字元可能會有損毀。

接下來,將任何 .NET 支援的編碼轉換為另一個 .NET 支援的編碼。 檢閱 Azure Functions 程式碼範例.NET 程式碼範例

提示

對於單一租用戶邏輯應用程式,您可以在本機執行轉換函式來改善效能並減少延遲。

Azure Functions 版本

下列範例適用於 Azure Functions 第 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)))
      });
  }
}

.NET 版本

下列範例適用於 .NET 標準版和 Azure Functions 第 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)))
                });
        }
    }

使用這些相同的概念,您也可以從工作流程傳送非 Unicode 承載

範例承載轉換

在此範例中,base64 編碼的範例輸入字串是包含重音字元的個人名稱:Héloïse

範例輸入:

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

範例輸出︰

{
    "text": "U01PcGJHL0RyM05s"
}

傳送非 Unicode 承載

如果您需要從工作流程傳送非 Unicode 承載,請反向執行將承載轉換為 UTF-8 的步驟。 盡可能地拉長在系統內保留 UTF-8 文字的時間。 接下來,使用相同的函式,將 base64 編碼的 UTF-8 字元轉換為所需的編碼。 然後,對文字套用 base64 解碼,並傳送您的承載。

轉換 AS2 的承載

您也可以將此解決方案與 AS2 v2 連接器中的非 Unicode 承載搭配使用。 如果您未將傳遞至 AS2 的承載轉換為 UTF-8,則可能會遇到承載解譯的問題。 這些問題可能會導致合作夥伴之間的 MIC 雜湊不相符,因為字元的解譯有誤。

下一步