Så här interagerar du med externa tjänster med hjälp av serverlogik

I den här guiden konfigurerar du en webbsida som använder serverlogik för att läsa, skriva, uppdatera och ta bort poster från httpclient-serverobjektet för externa tjänster.

Anmärkning

I det här exemplet används https://services.odata.org/TripPinRESTierService , men du kan använda andra offentligt tillgängliga kostnadsfria testverktyg.

Steg 1: Skapa en serverlogik

  1. Logga in på Power Pages.

  2. Välj webbplats + Redigera.

  3. Gå till arbetsytan Konfigurera och välj sedan Serverlogik (förhandsversion)

    Skärmbild som visar var du väljer serverlogik i arbetsytan för konfiguration.

  4. Välj +Ny serverlogik

  5. Ange namnet på serverlogik. Det här namnet används i API:et som resursidentifierare när du skapar serverlogik-API:et. Till exempel:

    Fastighet Exempelvärde
    Namn services.odata.org
    Visningsnamn Performing CRUD operations using OData service
  6. Välj +Lägg till roller för att tilldela lämplig webbroll. Administratörsroll i serverlogik har lagts till I det här exemplet väljer du Administratörer och loggar in som administratör senare för att fortsätta.

  7. Välj Lägg till.

  8. Välj serverlogik och välj Redigera kod.

    Välj redigera kod

  9. I dialogrutan Redigera i Microsoft Visual Studio Code för webben väljer du Öppna Visual Studio Code för att skapa den anpassade logiken.

    Du hittar fördefinierade metoder och skript i filen.

  10. Definiera serverlogikmetod för att läsa, redigera, skapa och ta bort åtgärder med hjälp av en extern tjänst.

    Lägg till följande baseUrl konstant före get() metoden

    
     const baseUrl  = "https://services.odata.org/TripPinRESTierService";
    
    
  11. getErsätt funktionerna , post, putoch exempel del med följande kod

    
    async function get() { 
       try { 
          Server.Logger.Log("GET called"); // Logger reference 
          if (!Server.Context.QueryParameters["username"]) { 
                const response = await Server.Connector.HttpClient.GetAsync( 
                   `${baseUrl}/People?$select=UserName,FirstName,LastName,MiddleName,Age`, 
                   {'content-type':'application/json'}); 
                return response; 
          } 
          else {             
                const id = Server.Context.QueryParameters["username"]; // Context reference 
                const response = await Server.Connector.HttpClient.GetAsync( 
                   `${baseUrl}(${id})/People?$select=UserName,FirstName,LastName,MiddleName,Age`, 
                   {'content-type':'application/json'}); 
                return response; 
          }         
       } catch (err) { 
          Server.Logger.Error("GET failed: " + err.message); 
          return JSON.stringify({ status: "error", method: "GET", message: err.message }); 
       } 
    } 
    
    async function post() { 
       try { 
          Server.Logger.Log("POST called"); 
          const data = JSON.parse(Server.Context.Body);            
          const url = `${baseUrl}/${data.serviceSession}/People`; 
          const { serviceSession, ...body } = data;  
          const response = await Server.Connector.HttpClient.PostAsync( 
                url,  
                JSON.stringify(body), 
                {'content-type':'application/json'}); 
          return response; 
       } catch (err) { 
          Server.Logger.Error("POST failed: " + err.message); 
          return JSON.stringify({ status: "error", method: "POST", message: err.message }); 
       } 
    }  
    
    async function put() { 
       try { 
          Server.Logger.Log("PUT called"); 
          const data = JSON.parse(Server.Context.Body);         
          const url = `${baseUrl}/${data.serviceSession}/People('${data.UserName}')`; 
          const { UserName, ...body1 } = data; 
          const { serviceSession, ...body } = body1; 
          const response = await Server.Connector.HttpClient.PatchAsync( 
                url,  
                JSON.stringify(body), 
                {'content-type':'application/json'}); 
          return response; 
       } catch (err) { 
          Server.Logger.Error("PUT failed: " + err.message); 
          return JSON.stringify({ status: "error", method: "PUT", message: err.message }); 
       } 
    }    
    
    async function del() { 
       try { 
          // "delete" keyword should not be used in script file. 
          Server.Logger.Log("DEL called"); 
          const username = Server.Context.QueryParameters["username"]; 
          const serviceSession = Server.Context.QueryParameters["serviceSession"]; 
          const url = `${baseUrl}/${serviceSession}/People('${username}')`; 
          const response = await Server.Connector.HttpClient.DeleteAsync( 
                url,  
                {'content-type':'application/json'}); 
          return response; 
       } catch (err) { 
          Server.Logger.Error("Deletion failed: " + err.message); 
          return JSON.stringify({ status: "error", method: "DEL", message: err.message }); 
       } 
    } 
    
  12. Spara filen.

    Tips/Råd

    Spara med Ctrl+S .

Steg 2: Skapa webbsida

  1. Starta Power Pages-designstudion.

  2. På arbetsytan Sidor väljer du + Sida.

    Lägga till en ny sida

  3. I dialogrutan Beskriv en sida för att skapa den väljer du Andra sätt att lägga till en sida.

  4. I dialogrutan Lägg till en sida anger du information.

    1. I rutan Namn anger du Serverlogik och väljer Starta från tom layout.
    2. Välj Lägg till.

    Ange värden för att lägga till en sida

  5. Välj alternativet Redigera kod i det övre högra hörnet.

  6. I dialogrutan Redigera i Visual Studio Code för webben väljer du Öppna Visual Studio Code.

  7. Ersätt koden som finns på HTML-sidan med följande:

    <div class="row sectionBlockLayout text-left" style="min-height: auto; padding: 8px;">
    <div class="container" style="display: flex; flex-wrap: wrap;">
       <div class="col-md-12 columnBlockLayout" style="padding: 16px; margin: 60px 0px; min-height: 200px;">
          <!-- Sample code for Web API demonstration -->
          <style>
          #processingMsg {
             padding: 6px 12px;
             background: #eee;
             border-radius: 4px;
             position: fixed;
             top: 10px;
             left: 50%;
             transform: translateX(-50%);
             display: none;
             z-index: 9999;
             text-align: center;
             font-weight: bold;
          }
    
          table {
             border-collapse: collapse;
             width: 100%;
             margin-top: 10px;
             font-family: Arial, sans-serif;
          }
    
          th,
          td {
             border: 1px solid #ccc;
             padding: 6px;
             text-align: left;
          }
    
          button {
             cursor: pointer;
             border: 1px solid #aaa;
             padding: 4px 8px;
             border-radius: 4px;
             background: #fff;
             font-size: 14px;
             margin-right: 2px;
          }
    
          button.add {
             color: green;
          }
    
          button.save {
             color: green;
          }
    
          button.cancel {
             color: orange;
          }
    
          button.delete {
             color: red;
          }
    
          input {
             width: 95%;
             box-sizing: border-box;
          }
    
          td.actions {
             white-space: nowrap;
          }
    
          td[data-attribute="UserName"] {
             background: #f9f9f9;
             cursor: default;
          }
          </style>
    
          <div id="processingMsg">Processing...</div>
          <div id="dataTable"></div>
    
          <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
          <script>
          $(function () {
    
             // Safe WebAPI wrapper for Power Pages
             (function (webapi, $) {
                function safeAjax(opts) {
                var d = $.Deferred();
                shell.getTokenDeferred().done(function (token) {
                   opts.headers = opts.headers || {};
                   opts.headers["__RequestVerificationToken"] = token;
                   $.ajax(opts)
                      .done((data, ts, jq) => validateLoginSession(data, ts, jq, d.resolve))
                      .fail(d.reject);
                }).fail(() => d.rejectWith(this, arguments));
                return d.promise();
                }
                webapi.safeAjax = safeAjax;
             })(window.webapi = window.webapi || {}, jQuery);
    
             // Notification overlay
             const notify = (() => {
                const $m = $('#processingMsg'); let s = 0, t;
                return {
                show: (msg = 'Processing...') => { $m.text(msg); if (!s) $m.show(); s++; },
                hide: () => { s = Math.max(0, s - 1); if (!s) t = setTimeout(() => $m.hide(), 200); }
                };
             })();
    
             function ajaxCall(msg, opts) {
                notify.show(msg);
                return webapi.safeAjax(opts)
                .fail(r => alert(r.responseJSON?.error?.message || 'Server error'))
                .always(notify.hide);
             }
    
             // Table columns
             const cols = [
                { name: 'UserName', label: 'User Name', editable: false },
                { name: 'FirstName', label: 'First Name' },
                { name: 'LastName', label: 'Last Name' },
                { name: 'MiddleName', label: 'Middle Name' },
                { name: 'Age', label: 'Age' }
             ];
    
             let data = [];
             let serviceSession = '';
             function render() {
                const html = `<table>
                <thead>
                   <tr>
                      ${cols.map(c => `<th>${c.label}</th>`).join('')}
                      <th>Actions <button class="add">➕</button></th>
                   </tr>
                </thead>
                <tbody>
                   ${data.map(r => `<tr data-UserName="${r.UserName}">
                      ${cols.map(c => `<td data-attribute="${c.name}" data-value="${r[c.name] || ''}">
                            ${r[c.name] || ''}
                      </td>`).join('')}
                      <td class="actions">
                            <button class="delete">🗑️</button>
                      </td>
                   </tr>`).join('')}
                </tbody>
          </table>`;
                $('#dataTable').html(html);
             }
    
             // Double click row to edit except username
             $('#dataTable').on('dblclick', 'tr', function () {
                const $tr = $(this);
                if ($tr.hasClass('editing')) return;
                $tr.addClass('editing');
                $tr.find('td[data-attribute]').each(function () {
                const $td = $(this);
                if ($td.data('attribute') === 'UserName') return;
                const old = $td.text().trim();
                $td.html(`<input type="text" value="${old}" data-attr="${$td.data('attribute')}"/>`);
                });
                $tr.find('.actions').append('<button class="save">✅</button><button class="cancel">❌</button>');
             });
    
             $('#dataTable').on('click', '.save', function () {
                const $tr = $(this).closest('tr');
                const username = $tr.data('username');
                const updates = {};
                $tr.find('input').each(function () {
                const attr = $(this).data('attr');
                let value = $(this).val().trim();
    
                if (attr === 'Age') {
                   value = Number(value);
                   if (isNaN(value)) value = null; // safety fallback
                }
    
                updates[attr] = value;
                });
    
                ajaxCall('Updating...', {
                type: 'PUT',
                url: `/_api/serverlogics/services.odata.org`,
                contentType: 'application/json',
                data: JSON.stringify(Object.assign({ UserName: username, serviceSession: `${serviceSession}` }, updates)),
                success: () => { Object.assign(data.find(x => x.UserName === username), updates); render(); }
                });
             });
    
             $('#dataTable').on('click', '.cancel', () => render());
    
             $('#dataTable').on('click', '.delete', function () {
                const username = $(this).closest('tr').data('username');
                if (!confirm('Delete ' + username + '?')) return;
                ajaxCall('Deleting...', {
                type: 'DELETE',
                url: `/_api/serverlogics/services.odata.org?username=${username}&serviceSession=${serviceSession}`,
                success: () => { data = data.filter(x => x.UserName !== username); render(); }
                });
             });
    
             $('#dataTable').on('click', '.add', function () {
                const r = {
                serviceSession: `${serviceSession}`,
                UserName: 'user' + Math.floor(Math.random() * 9000 + 1000),
                FirstName: 'New',
                LastName: 'Person',
                MiddleName: '',
                Age: 25
                };
                ajaxCall('Adding...', {
                type: 'POST',
                url: `/_api/serverlogics/services.odata.org`,
                contentType: 'application/json',
                data: JSON.stringify(r),
                success: () => { data.unshift(r); render(); }
                });
             });
    
             // Initial load
             ajaxCall('Loading...', {
                type: 'GET',
                url: `/_api/serverlogics/services.odata.org`,
                contentType: 'application/json'
             }).done(resp => {
                const parsed = JSON.parse(resp.data);
                const body = JSON.parse(parsed.Body);
    
                const ctx = body['@odata.context'];
                const match = ctx.match(/\\S\\[^)]*\\/);
                serviceSession = match ? match[0] : '';
    
                data = (body.value || []).map(r => ({
                UserName: r.UserName,
                FirstName: r.FirstName,
                LastName: r.LastName,
                MiddleName: r.MiddleName,
                Age: r.Age
                }));
                render();
             });
    
          });
          </script>
       </div>
    </div>
    </div>
    
  8. Spara filen

    Anmärkning

    Den här koden skapar ett interaktivt datatabellgränssnitt för att demonstrera CRUD-åtgärder (skapa, läsa, uppdatera, ta bort) med en extern OData-tjänst med hjälp av Power Pages-serverlogik. Den innehåller CSS-format för en dynamisk tabelllayout, ett överlägg för bearbetningsmeddelanden och JavaScript-funktioner som gör det möjligt för användare att visa data som hämtats från den externa tjänsten, lägga till nya poster genom att ➕ klicka på knappen, redigera befintliga poster genom att dubbelklicka på tabellrader (förutom fältet Användarnamn), spara ändringar med ✅, avbryta redigeringar med ❌och ta bort poster med knappen 🗑️ . Koden använder jQuery och en säker WebAPI-omslutning för att göra autentiserade AJAX-anrop till slutpunkten /_api/serverlogics/services.odata.org, hantera svarsdata för att parsa OData-kontext och hantera en tjänstsession för efterföljande åtgärder.

  9. Gå tillbaka till Power Pages-designern.

  10. I dialogrutan Du redigerar kod i Visual Studio Code för webben följer du anvisningarna och klickar på knappen Synkronisera .

Steg 3: Använd serverlogik för att läsa, visa, redigera, skapa och ta bort

Så här testar du serverlogikfunktionen:

  1. Välj Förhandsgranska och välj sedan Skrivbord.
  2. Logga in på din webbplats med användarkontot som har tilldelats rollen Serverlogikanvändare som du skapade tidigare. När vi valde rollen Administratörer i föregående steg loggar du i det här exemplet in som administratör.
  3. Gå till webbsidan serverlogik som skapades tidigare.
  4. Verifiera åtgärderna.

Översikt över serverlogik
Skapa serverlogik
ServerobjektSå här interagerar du med Dataverse-tabeller med hjälp av serverlogik