Zápis kódu do vlastního konektoru
Vlastní kód transformuje datové části požadavků a odpovědí nad rámec stávajících šablon zásad. Když je kód použit, má přednost před definicí bez kódu.
Další informace najdete v části Vytvoření vlastního konektoru od začátku.
Třída skriptů
Váš kód musí implementovat metodu nazvanou ExecuteAsync, která je volána za běhu. V této třídě můžete podle potřeby vytvářet další metody a volat je z metody ExecuteAsync. Název třídy musí být Script a musí implementovat ScriptBase.
public class Script : ScriptBase
{
public override Task<HttpResponseMessage> ExecuteAsync()
{
// Your code here
}
}
Definice podpůrných tříd a rozhraní
Třída Script odkazuje na následující třídy a rozhraní. Lze je použít pro místní testování a kompilaci.
public abstract class ScriptBase
{
// Context object
public IScriptContext Context { get; }
// CancellationToken for the execution
public CancellationToken CancellationToken { get; }
// Helper: Creates a StringContent object from the serialized JSON
public static StringContent CreateJsonContent(string serializedJson);
// Abstract method for your code
public abstract Task<HttpResponseMessage> ExecuteAsync();
}
public interface IScriptContext
{
// Correlation Id
string CorrelationId { get; }
// Connector Operation Id
string OperationId { get; }
// Incoming request
HttpRequestMessage Request { get; }
// Logger instance
ILogger Logger { get; }
// Used to send an HTTP request
// Use this method to send requests instead of HttpClient.SendAsync
Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken);
}
Ukázky
Skript Hello World
Tento ukázkový skript vždy vrátí Hello World jako odpověď na všechny požadavky.
public override async Task<HttpResponseMessage> ExecuteAsync()
{
// Create a new response
var response = new HttpResponseMessage();
// Set the content
// Initialize a new JObject and call .ToString() to get the serialized JSON
response.Content = CreateJsonContent(new JObject
{
["greeting"] = "Hello World!",
}.ToString());
return response;
}
Skript regulárního výrazu
Následující ukázka vezme nějaký text, který má odpovídat, a výraz regulárního výrazu a vrátí výsledek shody v odpovědi.
public override async Task<HttpResponseMessage> ExecuteAsync()
{
// Check if the operation ID matches what is specified in the OpenAPI definition of the connector
if (this.Context.OperationId == "RegexIsMatch")
{
return await this.HandleRegexIsMatchOperation().ConfigureAwait(false);
}
// Handle an invalid operation ID
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
response.Content = CreateJsonContent($"Unknown operation ID '{this.Context.OperationId}'");
return response;
}
private async Task<HttpResponseMessage> HandleRegexIsMatchOperation()
{
HttpResponseMessage response;
// We assume the body of the incoming request looks like this:
// {
// "textToCheck": "<some text>",
// "regex": "<some regex pattern>"
// }
var contentAsString = await this.Context.Request.Content.ReadAsStringAsync().ConfigureAwait(false);
// Parse as JSON object
var contentAsJson = JObject.Parse(contentAsString);
// Get the value of text to check
var textToCheck = (string)contentAsJson["textToCheck"];
// Create a regex based on the request content
var regexInput = (string)contentAsJson["regex"];
var rx = new Regex(regexInput);
JObject output = new JObject
{
["textToCheck"] = textToCheck,
["isMatch"] = rx.IsMatch(textToCheck),
};
response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = CreateJsonContent(output.ToString());
return response;
}
Předávací skript
Následující ukázka předá příchozí požadavek na back-end.
public override async Task<HttpResponseMessage> ExecuteAsync()
{
// Check if the operation ID matches what is specified in the OpenAPI definition of the connector
if (this.Context.OperationId == "ForwardAsPostRequest")
{
return await this.HandleForwardOperation().ConfigureAwait(false);
}
// Handle an invalid operation ID
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
response.Content = CreateJsonContent($"Unknown operation ID '{this.Context.OperationId}'");
return response;
}
private async Task<HttpResponseMessage> HandleForwardOperation()
{
// Example case: If your OpenAPI definition defines the operation as 'GET', but the backend API expects a 'POST',
// use this script to change the HTTP method.
this.Context.Request.Method = HttpMethod.Post;
// Use the context to forward/send an HTTP request
HttpResponseMessage response = await this.Context.SendAsync(this.Context.Request, this.CancellationToken).ConfigureAwait(continueOnCapturedContext: false);
return response;
}
Předávací a transformační skript
Následující ukázka předá příchozí požadavek a transformuje odpověď vrácenou z back-endu.
public override async Task<HttpResponseMessage> ExecuteAsync()
{
// Check if the operation ID matches what is specified in the OpenAPI definition of the connector
if (this.Context.OperationId == "ForwardAndTransformRequest")
{
return await this.HandleForwardAndTransformOperation().ConfigureAwait(false);
}
// Handle an invalid operation ID
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
response.Content = CreateJsonContent($"Unknown operation ID '{this.Context.OperationId}'");
return response;
}
private async Task<HttpResponseMessage> HandleForwardAndTransformOperation()
{
// Use the context to forward/send an HTTP request
HttpResponseMessage response = await this.Context.SendAsync(this.Context.Request, this.CancellationToken).ConfigureAwait(continueOnCapturedContext: false);
// Do the transformation if the response was successful, otherwise return error responses as-is
if (response.IsSuccessStatusCode)
{
var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(continueOnCapturedContext: false);
// Example case: response string is some JSON object
var result = JObject.Parse(responseString);
// Wrap the original JSON object into a new JSON object with just one key ('wrapped')
var newResult = new JObject
{
["wrapped"] = result,
};
response.Content = CreateJsonContent(newResult.ToString());
}
return response;
}
Podporované obory názvů
Nejsou podporovány všechny obory názvů C#. V současné době můžete používat funkce pouze z následujících oborů názvů.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using System.Xml.Linq;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
Ukázky na GitHub
Příklady v konektoru DocuSign přejděte na Power Platform Konektory na GitHubu.
Časté dotazy k vlastnímu kódu
Chcete-li se dozvědět více o vlastním kódu, přejděte na Krok 4: (Volitelné) Použijte podporu vlastního kódu.
Otázka: Je možné použít více skriptů na vlastní konektor?
Odpověď: Ne, je podporován pouze jeden soubor skriptu na vlastní konektor.
Otázka: Při aktualizaci vlastního konektoru se mi zobrazuje interní chyba serveru. V čem by mohl být problém?
Odpověď: S největší pravděpodobností se jedná o problém při kompilaci vašeho kódu. V budoucnu zobrazíme úplný seznam chyb při kompilaci, abychom vám ještě více usnadnili práci. Doporučujeme používat podpůrné třídy k testování chyb kompilace prozatím lokálně jako řešení.
Otázka: Mohu přidat protokolování do svého kódu a získat trasování pro ladění?
Odpověď: V současné době ne, ale podpora pro toto bude přidána v budoucnu.
Otázka: Jak mohu mezitím otestovat svůj kód?
A: Otestujte to lokálně a ujistěte se, že můžete zkompilovat kód pouze pomocí jmenných prostorů uvedených v podporovaných jmenných prostorech. Informace o místním testování najdete v části Zápis kódu do vlastního konektoru.
Otázka: Existují nějaké limity?
Odpověď: Ano. Skript musí dokončit spuštění do 2 minut a velikost souboru skriptu nesmí přesáhnout 1 MB. Tento nový 2minutový časový limit se vztahuje na všechny nově vytvořené vlastní konektory. U stávajících vlastních konektorů musí zákazníci aktualizovat konektor, aby se uplatnil nový časový limit.
Otázka: Mohu vytvořit vlastního http klienta v kódu skriptu?
A: V současné době ano, ale v budoucnu to zablokujeme. Doporučený způsob je použít this.Context.SendAsync metodu.
Otázka: Mohu použít vlastní kód s místní datovou bránou?
A: V současné době ne, ne.
Podpora Virtual Network
Když se konektor používá v Power Platform prostředí propojeném s virtuální sítí, platí omezení:
- Context.SendAsync používá veřejný koncový bod, a proto nemůže přistupovat k datům ze soukromých koncových bodů exponovaných ve Virtual Network.
Obecné známé problémy a omezení
Záhlaví OperationId může být v určitých oblastech vráceno v kódovaném formátu base64. Pokud je pro implementaci vyžadována hodnota OperationId, měla by být pro použití dekódována pomocí base64 způsobem podobným následujícímu.
public override async Task<HttpResponseMessage> ExecuteAsync()
{
string realOperationId = this.Context.OperationId;
// Resolve potential issue with base64 encoding of the OperationId
// Test and decode if it's base64 encoded
try {
byte[] data = Convert.FromBase64String(this.Context.OperationId);
realOperationId = System.Text.Encoding.UTF8.GetString(data);
}
catch (FormatException ex) {}
// Check if the operation ID matches what is specified in the OpenAPI definition of the connector
if (realOperationId == "RegexIsMatch")
// Refer to the original examples above for remaining details
}
Další krok
Vytvořte si vlastní konektor od začátku
Poskytnutí názorů
Velmi si vážíme vašich názorů na problémy s naší platformou konektorů nebo nových nápadů na funkce. Chcete-li poskytnout zpětnou vazbu, přejděte na Odeslat problémy nebo získejte nápovědu ke konektorům a vyberte typ zpětné vazby.