Aracılığıyla paylaş


Özel bağlayıcıya kod yazma

Özel kod, istek ve yanıt yüklerini varolan ilke şablonlarının kapsamı ötesinde dönüştürür. Kod kullanıldığında, kodsuz tanıma göre önceliklidir.

Daha fazla bilgi için Sıfırdan özel bağlayıcı oluşturma bölümüne gidin.

Betik sınıfı

Kodunuzun çalışma zamanı sırasında çağrılan ExecuteAsync adlı bir yöntem uygulaması gerekir. Gerektiğinde bu sınıfta başka yöntemler oluşturabilir ve bunları ExecuteAsync yönteminden çağırabilirsiniz. Sınıf adı Script olmalı ve ScriptBase'i uygulamalıdır .

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

Destekleyici sınıfların ve arabirimlerin tanımı

Aşağıdaki sınıflara ve arabirimlere Betik sınıfı tarafından başvurulur. Yerel test ve derleme için kullanılabilirler.

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

Örnekler

Merhaba Dünya betiği

Bu örnek betik dosyası, tüm isteklere yanıt olarak her zaman Merhaba Dünya'yı döndürür.

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 betiği

Aşağıdaki örnek eşleştirmek için bazı metinleri ve regex ifadesini alır ve yanıtta eşleşmenin sonucunu döndürür.

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

İletme betiği

Aşağıdaki örnek, gelen isteği arka uca iletir.

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

İletme ve dönüştür betiği

Aşağıdaki örnek gelen isteği iletir ve arka uçtan döndürülen yanıtı dönüştürür.

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

Desteklenen ad alanları

Tüm C# ad alanları desteklenmez. Şu anda, işlevleri yalnızca aşağıdaki ad alanlarından kullanabilirsiniz.

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 örnekleri

Bağlayıcıdaki DocuSign örnekler için GitHub'daki Bağlayıcılar'a Power Platform gidin.

Özel kodla ilgili SSS

Özel kod hakkında daha fazla bilgi edinmek için Adım 4: (İsteğe bağlı) Özel kod desteğini kullanma bölümüne gidin.

S: Her özel bağlayıcı için birden çok betik kullanmak mümkün müdür?
A: Hayır, özel bağlayıcı başına yalnızca bir betik dosyası desteklenir.

S: Özel bağlayıcımı güncelleştirirken dahili sunucu hatası alıyorum. Sorun ne olabilir?
C: Büyük olasılıkla, bu kodunuzu derlerken bir sorundur. Gelecekte bu deneyimi geliştirmek için derleme hatalarının tam listesini görüntüleyeceğiz. Geçici bir çözüm olarak şimdilik derleme hatalarını yerel olarak test etmek için destekleyici sınıfları kullanmanızı öneririz.

S: Koduma günlük kaydı ekleyebilir ve hata ayıklama için bir izleme alabilir miyim?
C: Şu anda değil, ancak gelecekte bunun için destek eklenecektir.

S: Bu arada kodumu nasıl test edebilirim?
A: Yerel olarak test edin ve yalnızca desteklenen ad alanlarında sağlananad alanlarını kullanarak kod derleyebildiğinizden emin olun. Yerel test hakkında daha fazla bilgi için Özel bağlayıcıda kod yazma'yagidin.

S: Herhangi bir sınır var mı?
Y: Evet. Betiğinizin yürütmeyi 2 dakika içinde tamamlaması gerekir ve betik dosyanızın boyutu 1 MB'ı aşamaz. Bu yeni 2 dakikalık zaman aşımı, yeni oluşturulan tüm özel bağlayıcılar için geçerlidir. Mevcut özel bağlayıcılar için müşterilerin yeni zaman aşımını uygulamak için bağlayıcıyı güncelleştirmesi gerekir.

S: Komut dosyası kodunda kendi http istemcimi oluşturabilir miyim?
C: Şu anda evet, ancak gelecekte bunu engelleyeceğiz. Önerilen yol bunu kullanmaktır . Context.SendAsync yöntemi.

S: Şirket içi veri ağ geçidi ile özel kod kullanabilir miyim?
C: Şu anda değil, hayır.

Sanal Ağ desteği

Bağlayıcı bir Sanal Ağa Power Platform bağlı birortamda kullanıldığında sınırlamalar geçerlidir:

  • Context.SendAsync genel bir uç nokta kullandığından Sanal Ağ'da açık olan özel uç noktalardan verilere erişemez.

Genel sınırlamalar ve bilinen sorunlar

OperationId üstbilgisi belirli bölgelerde base64 kodlamalı biçimde döndürülebilir. OperationId değeri bir uygulama için gerekliyse, aşağıdakine benzer bir kullanım için base64 ile kodlanmalıdır.

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
}

Sonraki adım

Sıfırdan özel bağlayıcı oluşturma

Geri bildirimde bulunun

Bağlayıcı platformumuzla veya yeni özellik fikirlerimizle ilgili sorunlar hakkındaki geri bildirimleriniz bizim için çok önemlidir. Geri bildirim sağlamak için Sorun gönderme veya bağlayıcılarla ilgili yardım alma bölümüne gidin ve geri bildirim türünüzü seçin.