Pisanie kodu w łączniku niestandardowym
Niestandardowy kod przekształca żądania i odpowiedzi poza zakresem istniejących szablonów polityki. Gdy używany jest kod, ma on pierwszeństwo przed definicją bez kodu.
Aby uzyskać więcej informacji, przejdź do tematu Tworzenie łącznika niestandardowego od podstaw.
Klasa skryptu
Kod musi zaimplementować metodę ExecuteAsync, która jest wywoływana w czasie wykonywania. W razie potrzeby można utworzyć inne metody w tej klasie i wywołać je za pomocą metody ExecuteAsync. Nazwa klasy musi mieć wartość Script i musi implementować ScriptBase.
public class Script : ScriptBase
{
public override Task<HttpResponseMessage> ExecuteAsync()
{
// Your code here
}
}
Definicje klas pomocy technicznej i interfejsów
Do klas skryptów odwołują się następujące klasy i interfejsy. Można ich używać do lokalnego testowania i kompilacji.
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);
}
Przykłady
Skrypt Hello World
Ten przykładowy skrypt zawsze zwraca Hello World jako odpowiedź dla wszystkich żądań.
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;
}
Skrypt regex
Poniższa próbka pobiera pewien tekst do dopasowania oraz wyrażenie regex i zwraca wynik dopasowania w odpowiedzi.
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;
}
Skrypt przesyłania dalej
Poniższy przykładowy przykład przesyła żądanie przychodzące do wewnętrznej bazy danych.
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;
}
Skrypt przesyłania dalej i przekształcenia
Poniższy przykład przesyła żądanie przychodzące i przekształci odpowiedź zwróconą z wewnętrznej bazy danych.
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;
}
Obsługiwane przestrzenie nazw
Nie wszystkie przestrzenie nazw języka C# są obsługiwane. Obecnie można używać funkcji tylko z następujących przestrzeni nazw.
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;
Przykłady GitHub
Aby zapoznać się z przykładami w łączniku DocuSign , przejdź do pozycji Power Platform Łączniki w usłudze GitHub.
Kod niestandardowy – FAQ
Aby dowiedzieć się więcej o kodzie niestandardowym, przejdź do kroku 4: (Opcjonalnie) Użyj obsługi kodu niestandardowego.
.: Czy można używać wielu skryptów na łącznik niestandardowy?
Odp.: Nie, obsługiwany jest tylko jeden plik skryptu na łącznik niestandardowy.
.: Otrzymuję wewnętrzny błąd serwera podczas aktualizowania łącznika niestandardowego. Co może być problemem?
O: Najprawdopodobniej jest to problem z kompilacją kodu. W przyszłości wyświetlimy pełną listę błędów kompilacji, aby poprawić jakość tego doświadczenia. Na razie zalecamy użycie klas pomocniczych do lokalnego testowania błędów kompilacji jako obejście problemu.
.: Czy mogę dodać rejestrowanie do mojego kodu i uzyskać ślad do debugowania?
Odp .: Obecnie nie, ale obsługa tego zostanie dodana w przyszłości.
P: Jak mogę przetestować mój kod w międzyczasie?
O: Przetestuj go lokalnie i upewnij się, że możesz skompilować kod tylko przy użyciu przestrzeni nazw dostępnych w obsługiwanych przestrzeniach nazw. Aby uzyskać informacje na temat testowania lokalnego, przejdź do tematu Pisanie kodu w łączniku niestandardowym.
P: Czy są jakieś limity?
Odpowiedź: Tak. Skrypt musi zostać wykonany w ciągu 2 minut, a rozmiar pliku skryptu nie może przekraczać 1 MB. Ten nowy 2-minutowy limit czasu ma zastosowanie do wszystkich nowo utworzonych łączników niestandardowych. W przypadku istniejących łączników niestandardowych klienci muszą zaktualizować łącznik, aby zastosować nowy limit czasu.
P: Czy mogę utworzyć własnego klienta http w kodzie skryptu?
O: Obecnie tak, ale zablokujemy to w przyszłości. Zalecanym sposobem jest skorzystanie z tego. Context.SendAsync .
.: Czy mogę użyć kodu niestandardowego z lokalną bramą danych?
Odp .: Obecnie nie, nie.
Pomoc techniczna usługi Virtual Network
Gdy łącznik jest używany w środowisku połączonym Power Platform z Virtual Network, obowiązują ograniczenia:
- Context.SendAsync używa publicznego punktu końcowego, dlatego nie może uzyskać dostępu do danych z prywatnych punktów końcowych ujawnionych w sieci wirtualnej.
Ogólne znane problemy i ograniczenia
Nagłówek OperationId może zostać zwrócony w formacie zakodowanym base64 w niektórych regionach. Jeśli wartość OperationId jest wymagana do implementacji, w celu jej użycia powinna ona zostać zdekodowana z formatu Base64 w sposób podobny do następującego.
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
}
Następny krok
Tworzenie łącznika niestandardowego od podstaw
Przekazywanie opinii
Jesteśmy wdzięczni za opinie na temat problemów z platformą łączników oraz pomysły na nowe funkcje. Aby przekazać opinię, przejdź do sekcji Przesyłanie problemów lub uzyskiwanie pomocy dotyczącej łączników i wybierz typ opinii.