Del via


Skrive kode i en egendefinert kobling

Egendefinert kode transformerer forespørsels- og svarnyttelaster utover omfanget av eksisterende policymaler. Når kode brukes, har den forrang over den kodeløse definisjonen.

Hvis du vil ha mer informasjon, kan du gå til Opprette en egendefinert kobling fra grunnen av.

Skript-klassen

Koden din må implementere en metode kalt ExecuteAsync, som kalles under kjøretid. Du kan opprette andre metoder i denne klassen etter behov, og kalle dem fra ExecuteAsync-metoden. Klassenavnet må være Script , og det må implementere ScriptBase.

public class Script : ScriptBase
{
    public override Task<HttpResponseMessage> ExecuteAsync()
    {
        // Your code here
    }
}

Definisjon av støtteklasser og grensesnitt

Følgende klasser og grensesnitt refereres til av Script-klassen. De kan brukes til lokal testing og kompilering.

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);
}

Eksempler

Hello World-manus

Dette eksempelskriptet returnerer alltid Hello World som svar for alle forespørsler.

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-skript

Følgende eksempel tar litt tekst for å samsvare med uttrykket for regulært uttrykk og returnerer resultatet av treffet i svaret.

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;
}

Videresending av skript

Følgende eksempel videresender den innkommende forespørselen til serverdelen.

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;
}

Videresende og transformere skript

Følgende eksempel videresender den innkommende forespørselen og transformerer svaret som returneres fra serverdelen.

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;
}

Navneområder som støttes

Ikke alle C#-navneområder støttes. For øyeblikket kan du bare bruke funksjoner fra følgende navneområder.

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-eksempler

Hvis du vil ha eksempler i koblingen, DocuSign kan du gå til Power Platform Koblinger i GitHub.

Vanlige spørsmål om tilpasset kode

Hvis du vil finne ut mer om egendefinert kode, kan du gå til Trinn 4: (Valgfritt) Bruk støtte for egendefinert kode.

Spørsmål: Er det mulig å bruke flere skript per egendefinert kobling?
Svar: Nei, bare én skriptfil per egendefinert kobling støttes.

Spørsmål: Jeg får en intern serverfeil når jeg oppdaterer den egendefinerte koblingen. Hva kan være problemet?
A: Mest sannsynlig er dette et problem med å kompilere koden din. I fremtiden viser vi hele listen over kompileringsfeil for å forbedre denne opplevelsen. Vi anbefaler at du bruker støtteklassene til å teste kompileringsfeil lokalt foreløpig som en løsning.

Spørsmål: Kan jeg legge til logging i koden min og få en sporing for feilsøking?
Svar: Ikke for øyeblikket, men støtte for dette vil bli lagt til i fremtiden.

Spørsmål: Hvordan kan jeg teste koden min i mellomtiden?
Svar: Test den lokalt, og sørg for at du kan kompilere kode ved å bruke bare navneområdene som er oppgitt i støttede navneområder. Hvis du vil ha informasjon om lokal testing, kan du gå til Skrive kode i en egendefinert kobling.

Spørsmål: Er det noen grenser?
Svar: Ja. Skriptet må fullføres innen 2 minutter, og størrelsen på skriptfilen kan ikke overstige 1 MB. Dette nye tidsavbruddet på 2 minutter gjelder for alle nyopprettede egendefinerte koblinger. For eksisterende egendefinerte koblinger må kundene oppdatere koblingen for å bruke det nye tidsavbruddet.

Spørsmål: Kan jeg lage min egen http-klient i skriptkode?
Svar: For øyeblikket ja, men vi vil blokkere dette i fremtiden. Den anbefalte måten er å bruke dette. Context.SendAsync-metoden .

Spørsmål: Kan jeg bruke egendefinert kode med den lokale datagatewayen?
Svar: Ikke for øyeblikket, nei.

Virtual Network-støtte

Når koblingen brukes i et Power Platform miljø som er koblet til et virtuelt nettverk, gjelder begrensninger:

  • Context.SendAsync bruker et offentlig endepunkt, og kan derfor ikke få tilgang til data fra private endepunkter som er eksponert på det virtuelle nettverket.

Generelle kjente problemer og begrensninger

OperationId-hodet kan returneres i base64-kodet format i visse områder. Hvis OperationId-verdien er nødvendig for en implementering, bør denne base64 dekodes for bruk på en måte som ligner på følgende.

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
}

Neste trinn

Opprette en egendefinert kobling fra grunnen av

gi tilbakemelding

Vi setter stor pris på tilbakemeldinger om problemer med koblingsplattformen vår, eller ideer til nye funksjoner. Hvis du vil gi tilbakemelding, kan du gå til Sende inn problemer eller få hjelp med koblinger og velge tilbakemeldingstype.