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'ya 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ı Betik olmalı ve ScriptBase 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

DocuSign bağlayıcısındaki örnekler için, GitHub'da Power Platform Bağlayıcıları'na 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ği kullanma bölümüne gidin.

S: Özel bağlayıcı başına birden çok betik kullanmak mümkün mü?
Y: Hayır, özel bağlayıcı başına yalnızca bir betik desteklenir.

S: Özel bağlayıcımı güncellerken bir iç sunucu hatası alıyorum. Sorun ne olabilir?
A: Büyük olasılıkla bu, kodunuzun derlenmesiyle ilgili bir sorundur. Gelecekte bu deneyimi geliştirmek için derleme hatalarının tam listesini görüntüleyeceğiz. Derleme hatalarını şimdilik yerel olarak sınamak için geçici çözüm olarak destekleyici sınıfları kullanmanızı öneririz.

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

S: Bu arada kodumu nasıl test edebilirim?
Y: Yerel olarak sınayın ve yalnızca desteklenen ad alanlarında sağlanan ad alanlarını kullanarak kod derlediğinize emin olun. Yerel sınama hakkında bilgi için Özel bağlayıcıda kod yazma'ya gidin.

S: Herhangi bir sınır var mı?
Y: Evet. Komut dosyanızın çalışması 2 dakika içinde tamamlanmalı ve komut dosyanızın boyutu 1 MB'ı geçmemelidir. 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 üzere bağlayıcıyı güncelleştirmesi gerekir.

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

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

Sanal Ağ desteği

Bağlayıcı, Sanal Ağa bağlı bir Power Platform ortamı üzerinde 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 bildirimde bulunmak için Sorun gönderme veya bağlayıcılarla ilgili yardım alma bölümüne gidip geri bildirim türünü seçin.