Instrukcje: interakcja z tabelami Dataverse przy użyciu logiki serwera

W tym przewodniku skonfigurujesz stronę internetową i niestandardowy szablon internetowy, który będzie używać logiki serwera do odczytywania, zapisywania, aktualizowania i usuwania rekordów z tabeli kontaktów.

Krok 1. Tworzenie logiki serwera

  1. Zaloguj się do usługi Power Pages.

  2. Wybierz witrynę + Edytuj.

  3. Przejdź do obszaru roboczego Konfigurowanie , a następnie wybierz pozycję Logika serwera (wersja zapoznawcza).

  4. Wybierz pozycję +Nowa logika serwera.

  5. Wprowadź nazwę logiki serwera. Ta nazwa jest używana w interfejsie API jako identyfikator zasobu podczas konstruowania interfejsu API logiki serwera.

    Przykład: operacje CRUD w Dataverse

  6. Wybierz pozycję +Dodaj role, aby przypisać odpowiednią rolę Internet.

  7. Wybierz 3 kropki (...) obok nazwy i wybierz pozycję Edytuj kod.

  8. Wybierz Otwórz Visual Studio Code, aby napisać logikę niestandardową. W pliku znajdziesz wstępnie zdefiniowane metody i skrypty.

  9. Zdefiniuj metodę logiki serwera, aby odczytywać, edytować, tworzyć i usuwać rekordy kontaktów.

    Przeczytaj: Dodaj poniższy skrypt wewnątrz metody get

    const entitySetName = Server.Context.QueryParameters["entitySetName"];
    if (!Server.Context.QueryParameters["id"]) {
        return Server.Connector.Dataverse.RetrieveMultipleRecords(entitySetName);
    } else {
        const id = Server.Context.QueryParameters["id"]; // Context reference
        return Server.Connector.Dataverse.RetrieveRecord(entitySetName, id);
    }
    

    Utwórz: Dodaj poniższy skrypt w metodzie POST

    const data = Server.Context.Body;
    const entitySetName = Server.Context.QueryParameters["entitySetName"];
    return Server.Connector.Dataverse.CreateRecord(entitySetName, data);
    

    Aktualizacja: Dodaj poniższy skrypt w metodzie put

    const id = Server.Context.QueryParameters["id"];
    const data = Server.Context.Body;
    return Server.Connector.Dataverse.UpdateRecord("accounts", id, data);
    

    Usuń: dodaj do metody usuwania

    const id = Server.Context.QueryParameters["id"];
    const entitySetName = Server.Context.QueryParameters["entitySetName"];
    Server.Logger.Log("Entity Set name:" + entitySetName);
    return Server.Connector.Dataverse.DeleteRecord(entitySetName, id);
    
  10. Zapisz plik.

  11. Oto kompletny kod logiki serwera, który można wkleić

    function get() {
     try {
         Server.Logger.Log("GET called"); // Logger reference
         const entitySetName = Server.Context.QueryParameters["entitySetName"];
         const additionParameters = Server.Context.QueryParameters['additionalParameters'];
         if (!Server.Context.QueryParameters["id"]) {
             const response = Server.Connector.Dataverse.RetrieveMultipleRecords(entitySetName,additionParameters);
             return response;
         }
         else{            
             const id = Server.Context.QueryParameters["id"]; // Context reference
             const response = Server.Connector.Dataverse.RetrieveRecord(entitySetName, id,additionParameters);
             return response;
         }        
     } catch (err) {
         Server.Logger.Error("GET failed: " + err.message);
         return JSON.stringify({ status: "error", method: "GET", message: err.message });
     }
     }
     function post() {
     try {
         Server.Logger.Log("POST called");
         const data = Server.Context.Body;
         const entitySetName = Server.Context.QueryParameters["entitySetName"];
          return Server.Connector.Dataverse.CreateRecord(entitySetName, data);
      } catch (err) {
         Server.Logger.Error("POST failed: " + err.message);
         return JSON.stringify({ status: "error", method: "POST", message: err.message });
     }
     } 
     function put() {
     try {
         Server.Logger.Log("PUT called");
         const id = Server.Context.QueryParameters["id"];
         const data = Server.Context.Body;
         const entitySetName = Server.Context.QueryParameters["entitySetName"];
         return Server.Connector.Dataverse.UpdateRecord(entitySetName, id, data);
      } catch (err) {
         Server.Logger.Error("PUT failed: " + err.message);
         return JSON.stringify({ status: "error", method: "PUT", message: err.message });
     }
     }   
     function del() {
     try {
         // "delete" keyword should not be used in script file.
         Server.Logger.Log("DEL called");
         const id = Server.Context.QueryParameters["id"];
           const entitySetName = Server.Context.QueryParameters["entitySetName"];
         return Server.Connector.Dataverse.DeleteRecord(entitySetName, id);
      } catch (err) {
         Server.Logger.Error("Deletion failed: " + err.message);
         return JSON.stringify({ status: "error", method: "DEL", message: err.message });
     }
     }
    

Krok 2. Tworzenie strony internetowej

  1. Uruchom studio projektowe Power Pages.

  2. W obszarze roboczym Strony wybierz pozycję + Strona.

  3. W oknie dialogowym Dodawanie strony wprowadź Logika serwera w polu Nazwa i wybierz układ Rozpocznij od nowa.

  4. Wybierz Dodaj.

  5. Wybierz opcję Edytuj kod w prawym górnym rogu.

  6. Wybierz pozycję Otwórz program Visual Studio Code.

  7. Skopiuj poniższy przykładowy fragment kodu i wklej go między <div></div> tagami sekcji strony.

    <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; }
    </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() {
        // --- safeAjax wrapper ---
        (function(webapi, $) {
            function safeAjax(ajaxOptions) {
                var dfd = $.Deferred();
                shell.getTokenDeferred().done(function(token) {
                    ajaxOptions.headers = ajaxOptions.headers || {};
                    ajaxOptions.headers["__RequestVerificationToken"] = token;
                    $.ajax(ajaxOptions)
                        .done((data, ts, jq) => validateLoginSession(data, ts, jq, dfd.resolve))
                        .fail(dfd.reject);
                }).fail(() => dfd.rejectWith(this, arguments));
                return dfd.promise();
            }
            webapi.safeAjax = safeAjax;
        })(window.webapi = window.webapi || {}, jQuery);
    
        // --- notification banner ---
        const notify = (function() {
            const $m = $('#processingMsg'); let s = 0, t;
            return {
                show: (msg = 'Processing...') => { $m.text(msg); if (!s) clearTimeout(t), $m.show(); s++; },
                hide: () => { s = Math.max(0, s - 1); if (!s) clearTimeout(t), t = setTimeout(() => $m.hide(), 300); }
            };
        })();
    
        function ajaxCall(msg, opts) {
            notify.show(msg);
            return webapi.safeAjax(opts)
                .fail(r => alert(r.responseJSON?.error?.message || 'Server logic not available'))
                .always(notify.hide);
        }
    
        // --- Table config ---
        const cols = [
            { name: 'firstname', label: 'First Name' },
            { name: 'lastname', label: 'Last Name' },
            { name: 'emailaddress1', label: 'Email' },
            { name: 'telephone1', label: 'Telephone' }
        ];
        let data = [];
    
        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-id="${r.id}" data-name="${r.fullname}">
                        ${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);
        }
    
        function addRecord(r) { data.unshift(r); render(); }
        function removeRecord(id) { data = data.filter(r => r.id !== id); render(); }
        function updateRecord(id, attr, val) { const r = data.find(r => r.id === id); if (r) { r[attr] = val; render(); } }
    
        // --- Events ---
        $('#dataTable').on('dblclick', 'tr', function() {
            const $tr = $(this);
            if ($tr.hasClass('editing')) return; // prevent double edit
            $tr.addClass('editing');
            $tr.data('original', $tr.find('td[data-attribute]').map(function() { return $(this).text(); }).get());
            $tr.find('td[data-attribute]').each(function() {
                const $td = $(this);
                const oldVal = $td.text();
                $td.html(`<input type="text" value="${oldVal}" data-attr="${$td.data('attribute')}" />`);
            });
            const $actions = $tr.find('td.actions');
            $actions.append('<button class="save">✅</button><button class="cancel">❌</button>');
        });
    
        $('#dataTable').on('click', '.save', function() {
            const $tr = $(this).closest('tr');
            const id = $tr.data('id');
            const updates = {};
            $tr.find('input').each(function() {
                updates[$(this).data('attr')] = $(this).val();
            });
            ajaxCall('Updating...', {
                type: 'PUT',
                url: `/_api/serverlogics/dataverse-crud-operations?entitySetName=contacts&id=${id}`,
                contentType: 'application/json',
                data: JSON.stringify(updates),
                success: () => { Object.assign(data.find(r => r.id === id), updates); render(); }
            });
        });
    
        $('#dataTable').on('click', '.cancel', function() {
            const $tr = $(this).closest('tr');
            const original = $tr.data('original');
            $tr.find('td[data-attribute]').each(function(i) {
                $(this).text(original[i]);
            });
            $tr.removeClass('editing');
            $tr.find('button.save, button.cancel').remove();
        });
    
        $('#dataTable').on('click', '.delete', function() {
            const $tr = $(this).closest('tr');
            if (confirm('Delete "' + $tr.data('name') + '"?')) {
                ajaxCall('Deleting...', {
                    type: 'DELETE',
                    url: `/_api/serverlogics/dataverse-crud-operations?entitySetName=contacts&id=${$tr.data('id')}`,
                    contentType: 'application/json',
                    success: () => removeRecord($tr.data('id'))
                });
            }
        });
    
        $('#dataTable').on('click', '.add', function() {
            const r = { firstname: 'Alton', lastname: 'Stott' + Math.floor(Math.random() * 900 + 100), emailaddress1: 'Alton.Stott@contoso.com', telephone1: '555-123-4567' };
            ajaxCall('Adding...', {
                type: 'POST',
                url: '/_api/serverlogics/dataverse-crud-operations?entitySetName=contacts',
                contentType: 'application/json',
                data: JSON.stringify(r),
                success: (res, s, xhr) => { r.id = xhr.getResponseHeader('entityid'); r.fullname = r.firstname + ' ' + r.lastname; addRecord(r); }
            });
        });
    
        ajaxCall('Loading...', {
            type: 'GET',
            url: '/_api/serverlogics/dataverse-crud-operations?entitySetName=contacts&additionalParameters=$select=fullname,firstname,lastname,emailaddress1,telephone1',
            contentType: 'application/json'
        }).done(res => {
            try {
                const p = JSON.parse(res.data); const b = JSON.parse(p.Body);
                data = (b.value || []).map(r => ({ ...r, id: r.contactid, fullname: r.fullname }));
                render();
            } catch (e) { console.error(e); }
        });
    });
    </script>
    

Krok 3. Konfigurowanie uprawnień

Tworzenie roli webowej

Jeśli obecnie nie masz roli sieci Web z uprawnieniami do tabeli, do której uzyskujesz dostęp za pośrednictwem logiki serwera lub potrzebujesz innego kontekstu uzyskiwania dostępu do danych, poniższe kroki pokazują, jak utworzyć nową rolę internetową i przypisać uprawnienia tabeli.

  1. Uruchom aplikację Do zarządzania portalem.
  2. W okienku po lewej stronie w sekcji Zabezpieczenia wybierz pozycję Role internetowe.
  3. Wybierz Nowy.
  4. W polu Nazwa wprowadź Użytkownik logiki serwera (lub dowolną nazwę, która najlepiej odzwierciedla rolę użytkownika korzystającego z tej funkcji).
  5. Na liście Strona internetowa wybierz rekord strony internetowej.
  6. Wybierz Zapisz.

Tworzenie uprawnień tabeli

  1. Uruchom studio projektowe Power Pages.
  2. Wybierz obszar roboczy Zabezpieczenia .
  3. W sekcji Ochrona wybierz pozycję Uprawnienia tabeli.
  4. Wybierz pozycję Nowe uprawnienie.
  5. W polu Nazwa wprowadź Uprawnienie do tabeli kontaktów.
  6. Na liście Nazwa tabeli wybierz pozycję Kontakt (kontakt).
  7. Na liście Typ dostępu wybierz pozycję Globalny.
  8. Wybierz pozycję Uprawnienia do odczytu, zapisu, tworzenia i usuwania .
  9. Wybierz pozycję + Dodaj role i wybierz wybraną lub utworzoną wcześniej rolę internetową .
  10. Zaznacz Zapisz i zamknij.

Dodaj kontakty do roli webowej

  1. Uruchom aplikację Do zarządzania portalem.
  2. W okienku po lewej stronie w sekcji Zabezpieczenia wybierz pozycję Kontakty.
  3. Wybierz kontakt, którego chcesz użyć w tym przykładzie dla logiki serwera.

    Uwaga / Notatka

    Ten kontakt jest kontem użytkownika używanym w tym przykładzie do testowania logiki serwera. Pamiętaj, aby wybrać prawidłowy kontakt w portalu.

  4. Wybierz Powiązane>Role sieciowe.
  5. Wybierz Dodaj istniejącą rolę witryny internetowej.
  6. Wybierz utworzoną wcześniej rolę użytkownika logiki serwera .
  7. Wybierz Dodaj.
  8. Zaznacz Zapisz i zamknij.

Krok 4. Używanie logiki serwera do odczytywania, wyświetlania, edytowania, tworzenia i usuwania

Aby przetestować funkcjonalność internetowego interfejsu API:

  1. Wybierz pozycję Wersja zapoznawcza, a następnie wybierz pozycję Pulpit.
  2. Zaloguj się do witryny przy użyciu konta użytkownika, do którego przypisano wcześniej utworzoną rolę użytkownika logiki serwera .
  3. Przejdź do utworzonej wcześniej strony internetowej logiki serwera .

Omówienie logiki serwera
Tworzenie logiki serwera
obiekty serwera