Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste guia, você configurará uma página da Web que usará a lógica do servidor para ler, gravar, atualizar e excluir registros do objeto de servidor httpclient de serviços externos.
Observação
Este exemplo usa https://services.odata.org/TripPinRESTierService o , mas você pode usar outras ferramentas de teste gratuitas disponíveis publicamente.
Etapa 1: Criar uma lógica de servidor
Inicie sessão no Power Pages.
Escolha site + Editar.
Navegue até o espaço de trabalho Configurar e selecione Lógica do servidor (visualização)
Selecione +Nova lógica do servidor
Indique o nome da lógica do servidor. Esse nome é usado na API como identificador de recurso durante a construção da API lógica do servidor. Por exemplo:
Propriedade Valor de Exemplo Nome services.odata.orgNome de exibição Performing CRUD operations using OData serviceSelecione +Adicionar funções para atribuir a função Web apropriada.
Neste exemplo, selecione Administradores e, posteriormente, entre como administrador para continuar.Selecione Adicionar.
Selecione a lógica do servidor e selecione Editar código.
Na caixa de diálogo Editar no Microsoft Visual Studio Code para a Web , selecione Abrir Código do Visual Studio para criar a lógica personalizada.
Você encontrará métodos e scripts predefinidos no arquivo.
Defina o método de lógica do servidor para ler, editar, criar, excluir operações usando o serviço externo.
Adicione a seguinte
baseUrlconstante antes doget()métodoconst baseUrl = "https://services.odata.org/TripPinRESTierService";Substitua as funções de exemplo
get,post,putedelpelo código a seguirasync 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 }); } }Salve o arquivo.
Gorjeta
Use Ctrl+S para salvar.
Etapa 2: Criar página da Web
Inicie o estúdio de design Power Pages.
No espaço de trabalho Páginas , selecione + Página.
Na caixa de diálogo Descrever uma página para criá-la , selecione Outras maneiras de adicionar uma página.
Na caixa de diálogo Adicionar uma página , insira os detalhes.
- Na caixa Nome , digite Lógica do servidor e selecione Iniciar a partir do layout em branco .
- Selecione Adicionar.
Selecione a opção Editar código no canto superior direito.
Na caixa de diálogo Editar no Visual Studio Code para a Web, selecione Abrir o Visual Studio Code.
Substitua o código encontrado na página HTML pelo seguinte:
<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>Salve o arquivo
Observação
Esse código cria uma interface de tabela de dados interativa para demonstrar operações CRUD (Criar, Ler, Atualizar, Excluir) com um serviço OData externo usando a lógica do servidor Power Pages. Ele inclui estilo CSS para um layout de tabela responsivo, uma sobreposição de notificação de processamento e funcionalidade JavaScript que permite aos usuários visualizar dados recuperados do serviço externo, adicionar novos registros clicando no ➕ botão, editar registros existentes clicando duas vezes nas linhas da tabela (exceto o campo Nome de usuário), salvar alterações com ✅, cancelar edições com ❌e excluir registros usando o 🗑botão ️. O código utiliza jQuery e uma camada de WebAPI segura para fazer chamadas AJAX autenticadas ao endpoint /_api/serverlogics/services.odata.org, processando os dados da resposta para interpretar o contexto OData e gerir uma sessão de serviço para operações subsequentes.
Retorne ao Power Pages Designer.
Na janela de diálogo Você está editando código no Visual Studio Code for the Web, siga as instruções e clique no botão Sincronizar.
Etapa 3: Usar a lógica do servidor para ler, exibir, editar, criar e excluir
Para testar a funcionalidade lógica do servidor:
- Selecione Pré-visualização e, em seguida, escolha Área de trabalho.
- Inicie sessão no seu site com a conta de utilizador à qual foi atribuída a função de utilizador da lógica de servidor que criou anteriormente. Como selecionamos a função Administradores na etapa anterior, neste exemplo, entre como administrador.
- Vá para a página da Web Lógica do servidor criada anteriormente.
- Verifique as operações.
Informações adicionais
Visão geral da lógica do servidor
Lógica do servidor de autor
Objetos do servidor: Como interagir com tabelas Dataverse usando a lógica do servidor