Como interagir com tabelas do Dataverse usando a lógica do servidor

Neste guia, você configurará uma página da Web e um modelo da Web personalizado que usará a lógica do servidor para ler, gravar, atualizar e excluir registros da tabela de contatos.

Etapa 1: Criar uma lógica de servidor

  1. Entre no Power Pages.

  2. Selecione + Editar no site.

  3. Navegue até o workspace Configuração e selecione Lógica de Servidor (versão prévia).

  4. Selecione +Nova lógica do servidor.

  5. Insira o nome da lógica do servidor. Esse nome é usado na API como identificador de recurso ao construir a API lógica do servidor.

    Exemplo: dataverse-crud-operations

  6. Selecione +Adicionar funções para atribuir a função Web apropriada.

  7. Selecione 3 ponto (...) ao lado do nome e selecione Editar código.

  8. Selecione Abrir o Visual Studio Code para criar a lógica personalizada. Você encontrará métodos e scripts predefinidos no arquivo.

  9. Defina o método lógico do servidor para ler, editar, criar e excluir os registros de contato.

    Leia: Adicionar o script abaixo dentro do método 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);
    }
    

    Criar: adicionar o script abaixo no método post

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

    Atualização: adicione o script abaixo no método put

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

    Excluir: adicionar dentro do método del

    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. Salve o arquivo.

  11. Aqui está o código lógico completo do servidor que pode ser colado

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

Etapa 2: Criar página da Web

  1. Inicie o estúdio de design do Power Pages.

  2. No workspace Páginas, selecione + Página.

  3. Na caixa de diálogo Adicionar uma página , insira a lógica do servidor na caixa Nome e selecione Iniciar do layout em branco .

  4. Selecione Adicionar.

  5. Selecione a opção Editar Código no canto superior direito.

  6. Selecione Abrir Visual Studio Code.

  7. Copie o snippet de código de exemplo a seguir e cole-o entre as <div></div> tags da seção da página.

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

Etapa 3: Configurar permissões

Criar uma função web

Se você atualmente não tiver uma função Web com permissões para a tabela que está acessando por meio da lógica do servidor ou exigir um contexto diferente de acesso aos dados, as etapas a seguir mostrarão como criar uma nova função Web e atribuir permissões de tabela.

  1. Inicie o aplicativo Gerenciamento de Portal.
  2. No painel esquerdo, na seção Segurança , selecione Funções Da Web.
  3. Selecione Novo.
  4. Na caixa Nome , insira o usuário lógico do servidor (ou qualquer nome que melhor reflita a função do usuário que está acessando essa funcionalidade).
  5. Na lista Site, selecione o registro do site.
  6. Clique em Salvar.

Criar permissões de tabela

  1. Inicie o estúdio de design do Power Pages.
  2. Selecione o espaço de trabalho Segurança.
  3. Na seção Proteger , selecione Permissões de Tabela.
  4. Selecione Nova permissão.
  5. Na caixa Nome, insira Permissão da Tabela de Contato.
  6. Na lista Nome da Tabela , selecione Contato (contato).
  7. Na lista Tipo de Acesso , selecione Global.
  8. Selecione Leitura, Gravação, Criação e Exclusão de privilégios.
  9. Selecione + Adicionar funções e selecione a função web que você selecionou ou criou anteriormente.
  10. Selecione Salvar e Fechar.

Adicionar contatos à função web

  1. Inicie o aplicativo Gerenciamento de Portal.
  2. No painel esquerdo, na seção Segurança , selecione Contatos.
  3. Selecione um contato que você deseja usar neste exemplo para a lógica do servidor.

    Observação

    Esse contato é a conta de usuário usada neste exemplo para testar a lógica do servidor. Selecione o contato correto em seu portal.

  4. Selecionefunções da Web relacionadas>.
  5. Selecione Adicionar Função Web Existente.
  6. Selecione a função de usuário lógico do servidor , criada anteriormente.
  7. Selecione Adicionar.
  8. Selecione Salvar e Fechar.

Etapa 4: Usar a lógica do servidor para ler, exibir, editar, criar e excluir

Para testar a funcionalidade da API Web:

  1. Selecione Visualizar e escolha Área de Trabalho.
  2. Entre em seu site com a conta de usuário que recebeu a função de usuário lógico do servidor que você criou anteriormente.
  3. Vá para a página da Web lógica do servidor criada anteriormente.

Visão geral da lógica do servidor
Lógica do servidor Author
Objetos do servidor