Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O código personalizado transforma os payloads de pedido e resposta para além do âmbito dos modelos de política existentes. Quando usas código, ele tem prioridade sobre a definição sem código.
Para mais informações, consulte Criar um conector personalizado do zero.
Classe de script
O seu código precisa de implementar um método chamado ExecuteAsync, que corre durante o tempo de execução. Pode criar outros métodos nesta classe conforme necessário e chamá-los a partir do ExecuteAsync método. O nome da classe deve ser Script e deve implementar ScriptBase.
public class Script : ScriptBase
{
public override Task<HttpResponseMessage> ExecuteAsync()
{
// Your code here
}
}
Definição de classes e interfaces de suporte
A Script classe faz referência às seguintes classes e interfaces. Use-os para testes e compilação locais.
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);
}
Exemplos
Script de Hello World
Este script de exemplo devolve sempre Hello World como resposta para todos os pedidos.
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;
}
Script de Regex
O exemplo seguinte utiliza algum texto para corresponder à expressão regex e devolve o resultado da correspondência na resposta.
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;
}
Script de reencaminhamento
O exemplo seguinte remete o pedido de entrada para o 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;
}
Script de reencaminhamento e transformação
O exemplo seguinte reencaminha o pedido de entrada e transforma a resposta devolvida a partir do 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 == "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;
}
Espaços de nomes suportados
Nem todos os espaços de nomes de C# são suportados. Atualmente, pode utilizar funções apenas a partir dos espaços de nomes seguintes.
Importante
A versão .NET atualmente suportada é .NET Standard 2.0.
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;
Exemplos do GitHub
Para obter exemplos no DocuSign conector, vá para Power Platform Conectores no GitHub.
Perguntas frequentes sobre código personalizado
Para saber mais sobre código personalizado, veja Passo 4: (Opcional) Use suporte a código personalizado.
P: Posso usar vários scripts por conector personalizado?R: Não, só pode usar um ficheiro de script por conector personalizado.
P: Recebo um erro interno no servidor ao atualizar o meu conector personalizado. Qual poderia ser o problema? R: Muito provavelmente, há um problema na compilação do seu código. No futuro, o sistema exibe a lista completa de erros de compilação para melhorar esta experiência. Por agora, use as classes de suporte para testar erros de compilação localmente como solução alternativa.
P: Posso adicionar registos ao meu código e obter um rastreio para depuração?R: Neste momento não, mas o suporte para esta funcionalidade será adicionado no futuro.
P: Como posso testar o meu código entretanto? R: Teste-o localmente e certifique-se de que consegue compilar código usando apenas os namespaces fornecidos nos namespaces suportados. Para informações sobre testes locais, consulte Escrever código num conector personalizado.
P: Existem limites?R: Sim. O script deve concluir a execução em 2 minutos e o tamanho do arquivo de script não pode exceder 1 MB. Este novo timeout de 2 minutos aplica-se a quaisquer conectores personalizados recém-criados. Para os conectores personalizados existentes, é necessário atualizar o conector para aplicar o novo tempo limite.
P: Posso criar o meu próprio cliente HTTP em código script?R: Atualmente, sim, mas o sistema bloqueia esta funcionalidade no futuro. A forma recomendada é utilizar o método this.Context.SendAsync.
P: Posso usar código personalizado com o gateway de dados local?R: Neste momento, não.
Suporte de Rede Virtual
Quando utiliza o conector num ambiente Power Platform ligado a uma rede virtual, aplicam-se as seguintes limitações:
-
Context.SendAsyncUsa um endpoint público, por isso não pode aceder a dados de endpoints privados na rede virtual.
Problemas conhecidos gerais e limitações
Em algumas regiões, o OperationId cabeçalho retorna em formato codificado base64. Se a sua implementação requer o OperationId valor, descodifique-o no base64 para uso.
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
}
Próximo passo
Criar um conector personalizado a partir do zero
Enviar comentários
Apreciamos os comentários sobre problemas com a nossa plataforma de conectores ou novas ideias de funcionalidades. Para fornecer comentários, vá para Enviar problemas ou obter ajuda com conectores e selecione seu tipo de feedback.