Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O código personalizado transforma cargas de solicitação e resposta além do escopo dos modelos de política existentes. Quando você usa código, ele tem precedência sobre a definição sem código.
Para obter mais informações, consulte Criar um conector personalizado do zero.
Classe de script
Seu código precisa implementar um método chamado ExecuteAsync, que é executado durante o runtime. Você pode criar outros métodos nessa classe conforme necessário e chamá-los do ExecuteAsync método. O nome da classe deve ser Script e deve ser implementado 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 teste 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 Olá, Mundo
Esse script de exemplo sempre retorna Olá, Mundo como a resposta para todas as solicitações.
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 a seguir usa algum texto para corresponder e a expressão regex e retorna 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 redirecionamento
O exemplo a seguir encaminha a solicitação 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 encaminhamento e transformação
O exemplo a seguir encaminha a solicitação de entrada e transforma a resposta retornada 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;
}
Namespaces com suporte
Nem todos os namespaces em C# têm suporte. No momento, você pode usar funções somente a partir dos namespaces a seguir.
Importante
A versão de .NET com suporte no momento é .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 ver exemplos do conector do DocuSign, acesse Conectores do Power Platform no GitHub.
Perguntas frequentes sobre código personalizado
Para saber mais sobre o código personalizado, consulte a Etapa 4: (Opcional) Usar suporte a código personalizado.
P: Posso usar vários scripts por conector personalizado?R: Não, você pode usar apenas um arquivo de script por conector personalizado.
P: Recebo um erro interno do servidor ao atualizar meu conector personalizado. Qual pode ser o problema? R: Provavelmente, há um problema ao compilar seu código. No futuro, o sistema exibe a lista completa de erros de compilação para melhorar essa experiência. Por enquanto, use as classes de suporte para testar erros de compilação localmente como uma solução alternativa.
P: Posso adicionar logs ao meu código e gerar um rastreamento para depuração?R: Ainda não, mas o suporte a esse recurso será adicionado no futuro.
P: Como posso testar meu código enquanto isso?R: Teste-o localmente e verifique se você pode compilar código usando apenas os namespaces fornecidos em namespaces com suporte. Para obter informações sobre testes locais, consulte Escrever código em um conector personalizado.
P: Há algum limite?R: Sim, sim. Seu script deve concluir a execução em 2 minutos e o tamanho do arquivo de script não pode exceder 1 MB. Esse novo tempo limite de 2 minutos se aplica a todos os conectores personalizados recém-criados. Para conectores personalizados existentes, você precisa atualizar o conector para aplicar o novo tempo limite.
P: Posso criar meu próprio cliente HTTP no código de script?R: Atualmente, sim, mas o sistema bloqueia esse recurso no futuro. A forma recomendada é usar o método this.Context.SendAsync.
P: Posso usar código personalizado com o gateway de dados local?R: Não no momento, não.
Suporte à Rede Virtual
Quando você usa o conector em um ambiente do Power Platform vinculado a uma rede virtual, as seguintes limitações se aplicam:
-
Context.SendAsyncusa um ponto de extremidade público, portanto, ele não pode acessar dados de pontos de extremidade privados na rede virtual.
Limitações e problemas gerais conhecidos
Em algumas regiões, o OperationId cabeçalho retorna no formato codificado em base64. Se sua implementação exigir o valor OperationId, decodifique-o em base64 para usá-lo.
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óxima etapa
Criar um conector personalizado do zero
Faça comentários
Agradecemos muito os comentários sobre problemas com nossa plataforma de conectores ou novas ideias de recursos. Para fornecer comentários, acesseEnviar problemas ou obter ajuda com conectores e selecione o tipo de comentário.