Com interactuar amb serveis externs mitjançant la lògica del servidor

En aquesta guia, configurareu una pàgina web que utilitzarà la lògica del servidor per llegir, escriure, actualitzar i suprimir registres de l'objecte servidor httpclient de serveis externs.

Nota

Aquest exemple utilitza https://services.odata.org/TripPinRESTierService , però podeu utilitzar altres eines de prova gratuïtes disponibles públicament.

Pas 1: Crear una lògica de servidor

  1. Inicieu la sessió al Power Pages.

  2. Seleccioneu lloc + Edita.

  3. Aneu a l'àrea de treball Configura i seleccioneu Lògica del servidor (visualització prèvia)

    Captura de pantalla que mostra on seleccionar la lògica del servidor a l'espai de treball Configura.

  4. Seleccioneu +Lògica del servidor nova

  5. Introduïu el nom de la lògica del servidor. Aquest nom s'utilitza a l'API com a identificador de recursos mentre es construeix l'API lògica del servidor. Per exemple:

    Propietat Valor d'exemple
    Nom services.odata.org
    Nom de visualització Performing CRUD operations using OData service
  6. Seleccioneu +Afegeix funcions per assignar la funció web adequada. S'ha afegit la funció d'administrador a la lògica del servidor En aquest exemple, seleccioneu Administradors i, posteriorment , inicieu la sessió com a administrador per continuar.

  7. Seleccioneu Afegeix.

  8. Seleccioneu la lògica del servidor i seleccioneu Edita el codi.

    Seleccioneu el codi d'edició

  9. Al diàleg Edita al Microsoft Visual Studio Code per al web , seleccioneu Obre el Visual Studio Code per crear la lògica personalitzada.

    Trobareu mètodes i scripts predefinits al fitxer.

  10. Definiu el mètode lògic del servidor per llegir, editar, crear i suprimir operacions mitjançant un servei extern.

    Afegiu la constant següent baseUrl abans del get() mètode

    
     const baseUrl  = "https://services.odata.org/TripPinRESTierService";
    
    
  11. Substituïu les funcions , post, puti del d'exemple getpel codi següent

    
    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. Deseu el fitxer.

    Propina

    Utilitzeu Ctrl+S per desar.

Pas 2: Crea una pàgina web

  1. Inicieu l'estudi de disseny del Power Pages.

  2. A l'espai de treball Pages , seleccioneu + Pàgina.

    Afegir una pàgina nova

  3. Al diàleg Descriu una pàgina per crear-la , seleccioneu Altres maneres d'afegir una pàgina.

  4. Al diàleg Afegeix una pàgina , introduïu detalls.

    1. Al quadre Nom , introduïu Lògica del servidor i seleccioneu Comença des d'un disseny en blanc .
    2. Seleccioneu Afegeix.

    Introduïu valors per afegir una pàgina

  5. Seleccioneu l'opció Edita el codi a l'extrem superior dret.

  6. Al diàleg Edita al Visual Studio Code per al web, seleccioneu Obre el Visual Studio Code.

  7. Substituïu el codi que es troba a la pàgina HTML pel següent:

    <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. Desa el fitxer

    Nota

    Aquest codi crea una interfície interactiva de taula de dades per demostrar les operacions CRUD (Creació, lectura, actualització, supressió) amb un servei OData extern mitjançant la lògica del servidor del Power Pages. Inclou estil CSS per a un disseny de taula responsiu, una superposició de notificació de processament i funcionalitat JavaScript que permet als usuaris veure les dades recuperades del servei extern, afegir nous registres fent clic al ➕ botó, editar registres existents fent doble clic a les files de la taula (excepte el camp Nom d'usuari), desar els canvis amb ✅, cancel·lar edicions amb ❌i suprimir registres mitjançant el 🗑botó ️. El codi utilitza jQuery i un embolcall WebAPI segur per fer trucades AJAX autenticades a l'extrem /_api/serverlogics/services.odata.org, gestionant les dades de resposta per analitzar el context OData i gestionar una sessió de servei per a operacions posteriors.

  9. Torneu al dissenyador de pàgines del Power.

  10. Al diàleg Esteu editant codi al Visual Studio Code per al web , seguiu les instruccions i feu clic al botó Sincronitza .

Pas 3: Utilitzeu la lògica del servidor per llegir, veure, editar, crear i suprimir

Per provar la funcionalitat lògica del servidor:

  1. Seleccioneu Visualització prèvia i, a continuació, trieu Escriptori.
  2. Inicieu la sessió al vostre lloc amb el compte d'usuari al qual s'ha assignat la funció d'usuari de lògica del servidor que heu creat anteriorment. Com que hem seleccionat la funció Administradors al pas anterior, en aquest exemple, inicieu la sessió com a administrador.
  3. Aneu a la pàgina web de lògica del servidor creada anteriorment.
  4. Verifiqueu les operacions.

Informació general de la lògica del servidor
Lògica del servidor d'autor
Objectes de servidorCom interactuar amb les taules del Dataverse mitjançant la lògica del servidor