PowerApps - отображение изображения, полученного пользовательским соединителем через API ASP.NET

Я использую размещенный в Azure ASP.NET API для доставки элементов из моего бэкэнда в приложение PowerApps canvas. Некоторым элементам назначены изображения. В этих случаях я предоставляю идентификатор изображения, чтобы загрузить изображение по требованию с помощью метода GetImage(id). В этом методе я возвращаю содержимое в HTTPResponse. Это работает до сих пор. Я могу вызвать метод из браузера, и изображение отображается. На мобильном устройстве я не могу использовать URL-адрес напрямую, поскольку соединение защищено Azure AD. Мне нужно получить изображение, используя метод результата моего пользовательского соединителя. К сожалению, я не могу найти способ заполнить элемент управления изображением строкой, содержащей необработанные данные изображения. Как это можно сделать? Я мог бы вернуть любой другой тип в API, если это решит проблему.

С уважением

Sven

1 ответ

Вы можете вернуть изображение прямо из пользовательского соединителя в приложение. В ответе на пользовательский API вам нужно определить формат как двоичный, а медиа-тип как изображение.

        "responses": {
          "default": {
            "description": "default",
            "schema": {
              "type": "string",
              "format": "binary",
              "x-ms-media-kind": "image"
            }
          }
        },

Например, это одна из функций Azure, которая возвращает штрих-код с заданным кодом (не готов к производству, скорее для проверки концепции):

#r "System.Drawing"

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using ZXing;
using ZXing.Common;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{

    // parse query parameter
    string code = GetQueryStringValue(req, "code");
    string widthStr = GetQueryStringValue(req, "width") ?? "100";
    string heightStr = GetQueryStringValue(req, "height") ?? "50";

    var width = int.Parse(widthStr);
    var height = int.Parse(heightStr);

    if (code == null)
    {
        // Get request body
        dynamic body = await req.Content.ReadAsAsync<object>();
        code = body?.code;
    } 

    if (code == null)
    {
        return req.CreateResponse(
            HttpStatusCode.BadRequest,
            "Please pass a code on the query string or in the request body");
    }

    var writer = new BarcodeWriterPixelData
    {
        Format = BarcodeFormat.UPC_A,
        Options = new EncodingOptions { Height = height, Width = width }
    };

    if (string.IsNullOrEmpty(code))
    {
        code = "123456789012";
    }

    var pixelData = writer.Write(code);
    var ms = new MemoryStream();
    var bitmap = pixelData.ToBitmap();
    bitmap.Save(ms, ImageFormat.Png);
    ms.Position = 0;

    var content = new StreamContent(ms);
    content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
    return new HttpResponseMessage(HttpStatusCode.OK) { Content = content };
}

private static string GetQueryStringValue(HttpRequestMessage req, string name)
{
    return req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, name, true) == 0)
        .Value;
}

Он использует пакет ZXing NuGet, который должен быть объявлен в Project.json:

{
  "frameworks": {
    "net46":{
      "dependencies": {
        "ZXing.Net": "0.16.4"
      }
    }
   }
}

Затем вы определяете тип

{
  "swagger": "2.0",
  "info": {
    "title": "BarcodeGenerator",
    "description": "Barcode generator",
    "version": "1.0"
  },
  "host": "YOUR_FUNCTION_APP_NAME_HERE.azurewebsites.net",
  "basePath": "/api/",
  "schemes": [
    "https"
  ],
  "consumes": [],
  "produces": [],
  "paths": {
    "/BarcodeGenerator": {
      "get": {
        "responses": {
          "default": {
            "description": "default",
            "schema": {
              "type": "string",
              "format": "binary",
              "x-ms-media-kind": "image"
            }
          }
        },
        "summary": "Generate barcode",
        "description": "Generate a barcode.",
        "operationId": "GenerateBarcode",
        "parameters": [
          {
            "name": "code",
            "in": "query",
            "required": true,
            "type": "integer"
          },
          {
            "name": "width",
            "in": "query",
            "required": false,
            "type": "integer"
          },
          {
            "name": "height",
            "in": "query",
            "required": false,
            "type": "integer"
          }
        ]
      }
    }
  },
  "definitions": {},
  "parameters": {},
  "responses": {},
  "securityDefinitions": {},
  "security": [],
  "tags": []
}

Надеюсь это поможет!

Другие вопросы по тегам