Code in een aangepaste connector schrijven
Aangepaste code transformeert payloads voor aanvragen en antwoorden buiten het bereik van bestaande beleidssjablonen. Wanneer er code wordt gebruikt, heeft deze voorrang op de codeloze definitie.
Ga voor meer informatie naar Een aangepaste connector maken.
Script-klasse
Uw code moet een methode implementeren met de naam ExecuteAsync, die tijdens runtime wordt aangeroepen. U kunt indien nodig andere methoden in deze klasse maken en deze aanroepen vanuit de methode ExecuteAsync. De klassenaam moet zijn Script en deze moet ScriptBase implementeren.
public class Script : ScriptBase
{
public override Task<HttpResponseMessage> ExecuteAsync()
{
// Your code here
}
}
Definitie van ondersteunende klassen en interfaces
Naar de volgende klassen en interfaces wordt verwezen door de Script-klasse. Deze kunnen worden gebruikt voor lokaal testen en compileren.
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);
}
Voorbeelden
Hallo Wereld-script
Dit voorbeeldscript retourneert altijd Hallo Wereld als antwoord voor alle verzoeken.
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;
}
Regex-script
In het volgende voorbeeld is wat tekst nodig om te vergelijken en de regex-expressie en wordt het resultaat van de overeenkomst in de respons geretourneerd.
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;
}
Doorstuurscript
In het volgende voorbeeld wordt de binnenkomende aanvraag doorgestuurd naar de 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;
}
Doorsturen en transformeren-script
In het volgende voorbeeld wordt de binnenkomende aanvraag doorgestuurd en wordt de respons van de back-end getransformeerd.
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;
}
Ondersteunde naamruimten
Niet alle C#-naamruimten worden ondersteund. Momenteel kunt u alleen functies uit de volgende naamruimten gebruiken.
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;
GitHub-voorbeelden
Voor voorbeelden in de DocuSign-connector gaat u naar Power Platform-connectors in GitHub.
Veelgestelde vragen over aangepaste code
Ga voor meer informatie over aangepaste code naar Stap 4: (Optioneel) gebruik van ondersteuning voor aangepaste code.
V: Is het mogelijk om meerdere scripts per aangepaste connector te gebruiken?
A: Nee, er wordt slechts één scriptbestand per aangepaste connector ondersteund.
V: Ik krijg een interne serverfout bij het updaten van mijn aangepaste connector. Wat kan het probleem zijn?
A: Hoogstwaarschijnlijk is dit een probleem bij het compileren van uw code. In de toekomst geven we de volledige lijst met compilatiefouten weer om deze ervaring te verbeteren. We raden aan om de ondersteunende klassen te gebruiken om compilatiefouten voorlopig lokaal te testen als een tijdelijke oplossing.
V: Kan ik logboekregistratie aan mijn code toevoegen en een trace voor foutopsporing krijgen?
A: Momenteel niet, maar ondersteuning hiervoor zal in de toekomst worden toegevoegd.
V: Hoe kan ik in de tussentijd mijn code testen?
A: Test de code lokaal en zorg ervoor dat u code kunt compileren met alleen de naamruimten die in ondersteunde naamruimten is vermeld. Ga voor informatie over lokaal testen naar Code schrijven in een aangepaste connector.
V: Zijn er limieten?
A: Ja. Uw script moet binnen 5 seconden worden uitgevoerd en uw scriptbestand mag niet groter zijn dan 1 MB.
V: Kan ik mijn eigen http-client in scriptcode maken?
A: Momenteel wel, maar we zullen dit in de toekomst blokkeren. De aanbevolen manier is om de this.Context.SendAsync-methode te gebruiken.
V: Kan ik aangepaste code gebruiken met de on-premises gegevensgateway?
A: Momenteel niet.
Virtual Network-ondersteuning
Wanneer de connector wordt gebruikt in een Power Platform-omgeving die is gekoppeld aan een Virtual Network, zijn er beperkingen van toepassing:
- Context.SendAsync maakt gebruik van een openbaar eindpunt en heeft daarom geen toegang tot gegevens van privé-eindpunten die beschikbaar zijn in het Virtual Network.
Algemene bekende problemen en beperkingen
De OperationId-header kan in bepaalde regio's worden geretourneerd in een base64-gecodeerde indeling. Als de waarde van OperationId is vereist voor een implementatie, moet deze voor gebruik met base64 worden gedecodeerd op een wijze die vergelijkbaar is met de volgende.
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
}
Volgende stap
Een volledig nieuwe aangepaste connector maken
Feedback geven
We stellen feedback over problemen met ons connectorplatform of ideeën voor nieuwe functies zeer op prijs. Om feedback te geven, gaat u naar Problemen melden of hulp krijgen met connectoren en selecteer uw feedbacktype.