教學課程:使用入口網站 Web API
注意
自 2022 年 10 月 12 日起,Power Apps 入口網站為 Power Pages。 其他資訊:Microsoft Power Pages 現在已推出 (部落格)
我們很快就會遷移並將 Power Apps 入口網站文件與 Power Pages 文件併合。
在此教學課程中,您將設定一個網頁和自訂 Web 範本,這些範本將使用 Web API 從連絡人資料表中讀取、寫入、更新和刪除記錄。
注意
您可以按照此範例中的步驟變更資料列名,或使用其他資料表。
步驟 1。 建立網站設定
您必須先使用入口網站管理應用程式來啟用必要的網站設定,才能使用入口網站 API。 網站設定會根據您要在與 Web API 互動時所使用的資料表而定。
移至 Power Apps。
在左窗格中,選取 應用程式。
選取 入口網站管理 應用程式。
在 入口網站管理 應用程式的左窗格中,選取 網站設定。
選取 新增。
在 名稱 方塊中,輸入 Webapi/contact/enabled。
在 網站 清單中,選取您的網站記錄。
在 值 方塊中,輸入 true。
選取 儲存並關閉。
選取 新增。
在 名稱 方塊中,輸入 Webapi/contact/fields。
在 網站 清單中,選取您的網站記錄。
在 值 方塊中,輸入
firstname,lastname,fullname,emailaddress1,telephone1選取 儲存並關閉。
選取 新增。
在 名稱 方塊中,輸入 Webapi/error/innererror。
在 網站 清單中,選取您的網站記錄。
在 值 方塊中,輸入 true。
選取 儲存並關閉。
驗證 Web API 的網站設定。
步驟 2: 設定權限
您必須設定權限,才能讓使用者使用 Web API 功能。 在此範例中,您將為資料表權限啟用連絡人資料表,使用 Web API 建立 Web 角色,將連絡人資料表的資料表權限新增到此 Web 角色,然後將 Web 角色新增到使用者,以允許他們使用 Web API。
在 入口網站管理 應用程式的左窗格中,選取 資料表權限。
選取 新增。
在 名稱 方塊中,輸入 連絡人資料表權限。
在 資料表名稱 清單中,選取 連絡人 (連絡人)。
在 網站 清單中,選取您的網站記錄。
在 存取模式 清單中,選取 全域。
選取讀取、寫入、建立和刪除權限。
選取 儲存並關閉。
建立 Web 角色
您可以使用您網站中現有的 Web 角色,或是建立新的 Web 角色。
在左窗格中,選取 Web 角色 。
選取 新增。
在 名稱 方塊中,輸入 Web API 使用者 (或任何最能反映存取此功能使用者角色的名稱)。
在 網站 清單中,選取您的網站記錄。
選取 儲存。
新增相關資料表權限
在新的或現有的 Web 角色中,選取 相關 > 資料表權限。
選取 新增現有的資料表權限。
選取 連絡人資料表權限,這是先前建立的權限。
選取 新增。
選取 儲存並關閉。
將連絡人新增至 Web 角色
在左窗格中,選取 連絡人。
選擇要在此範例中用於 Web API 的連絡人。
注意
此連絡人是此範例中用來測試 Web API 的使用者帳戶。 請務必在您的入口網站中選取正確的連絡人。
選取 相關 > Web 角色。
選取 新增現有 Web 角色。
選取先前建立的 WEB API 使用者 角色。
選取 新增。
選取 儲存並關閉。
步驟 3: 建立網頁
現在您已啟用 Web API 並已設定使用者權限,請建立含範例程式碼的網頁,以查看、編輯、建立及刪除記錄。
在 入口網站管理 應用程式的左窗格中,選取網頁。
選取新增。
在名稱方塊中,輸入 webapi。
在網站清單中,選取您的網站記錄。
在上層頁面,選取首頁。
在部分 URL,請輸入 webapi。
在頁面範本,選取首頁。
在發佈狀態,選取已發佈。
選取儲存。
選取相關 > 網頁。
從網頁相關檢視表中,選取 webapi。
向下捲動至內容區段,然後移至複製 (HTML) (HTML 設計工具)。
選取 HTML 索引標籤。
複製下列範例程式碼片段並在 HTML 設計工具中貼上。
<!-- Sample code for Web API demonstration --> <style> #processingMsg { width: 150px; text-align: center; padding: 6px 10px; z-index: 9999; top: 0; left: 40%; position: fixed; -webkit-border-radius: 0 0 2px 2px; border-radius: 0 0 2px 2px; -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); display: none; } table td[data-attribute] .glyphicon-pencil { margin-left: 5px; opacity: 0; } table td[data-attribute]:hover .glyphicon-pencil { opacity: 0.7; } </style> <script> $(function() { //Web API ajax wrapper (function(webapi, $) { function safeAjax(ajaxOptions) { var deferredAjax = $.Deferred(); shell.getTokenDeferred().done(function(token) { // Add headers for ajax if (!ajaxOptions.headers) { $.extend(ajaxOptions, { headers: { "__RequestVerificationToken": token } }); } else { ajaxOptions.headers["__RequestVerificationToken"] = token; } $.ajax(ajaxOptions) .done(function(data, textStatus, jqXHR) { validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve); }).fail(deferredAjax.reject); //ajax }).fail(function() { deferredAjax.rejectWith(this, arguments); // On token failure pass the token ajax and args }); return deferredAjax.promise(); } webapi.safeAjax = safeAjax; })(window.webapi = window.webapi || {}, jQuery) // Notification component var notificationMsg = (function() { var $processingMsgEl = $('#processingMsg'), _msg = 'Processing...', _stack = 0, _endTimeout; return { show: function(msg) { $processingMsgEl.text(msg || _msg); if (_stack === 0) { clearTimeout(_endTimeout); $processingMsgEl.show(); } _stack++; }, hide: function() { _stack--; if (_stack <= 0) { _stack = 0; clearTimeout(_endTimeout); _endTimeout = setTimeout(function() { $processingMsgEl.hide(); }, 500); } } } })(); // Inline editable table component var webAPIExampleTable = (function() { var trTpl = '<% _.forEach(data, function(data){ %>' + '<tr data-id="<%=data.id%>" data-name="<%=data.fullname%>">' + '<% _.forEach(columns, function(col){ %>' + '<td data-attribute="<%=col.name%>" data-label="<%=col.label%>" data-value="<%=data[col.name]%>">' + '<%-data[col.name]%><i class="glyphicon glyphicon-pencil"></i>' + '</td>' + '<% }) %>' + '<td>' + '<button class="btn btn-default delete" type="submit"><i class="glyphicon glyphicon-trash" aria-hidden="true"></i></button>' + '</td>' + '</tr>' + '<% }) %>'; var tableTpl = '<table class="table table-hover">' + '<thead>' + '<tr>' + '<% _.forEach(columns, function(col){ %>' + '<th><%=col.label%></th>' + '<% }) %>' + '<th>' + '<button class="btn btn-default add" type="submit">' + '<i class="glyphicon glyphicon-plus" aria-hidden="true"></i> Add Sample Record' + '</button>' + '</th>' + '</tr>' + '</thead>' + '<tbody>' + trTpl + '</tbody>' + '</table>'; function getDataObject(rowEl) { var $rowEl = $(rowEl), attrObj = { id: $rowEl.attr('data-id'), name: $rowEl.attr('data-name') }; $rowEl.find('td').each(function(i, el) { var $el = $(el), key = $el.attr('data-attribute'); if (key) { attrObj[key] = $el.attr('data-value'); } }) return attrObj; } function bindRowEvents(tr, config) { var $row = $(tr), $deleteButton = $row.find('button.delete'), dataObj = getDataObject($row); $.each(config.columns, function(i, col) { var $el = $row.find('td[data-attribute="' + col.name + '"]'); $el.on('click', $.proxy(col.handler, $el, col, dataObj)); }); //User can delete record using this button $deleteButton.on('click', $.proxy(config.deleteHandler, $row, dataObj)); } function bindTableEvents($table, config) { $table.find('tbody tr').each(function(i, tr) { bindRowEvents(tr, config); }); $table.find('thead button.add').on('click', $.proxy(config.addHandler, $table)); } return function(config) { var me = this, columns = config.columns, addHandler = config.addHandler, deleteHandler = config.deleteHandler, $table; me.render = function(el) { $table = $(el).html(_.template(tableTpl)({ columns: columns, data: me.data })).find('table'); bindTableEvents($table, { columns: columns, addHandler: addHandler, deleteHandler: deleteHandler }); } me.addRecord = function(record) { $table.find('tbody tr:first').before(_.template(trTpl)({ columns: columns, data: [record] })); bindRowEvents($table.find('tbody tr:first'), config); } me.updateRecord = function(attributeName, newValue, record) { $table.find('tr[data-id="' + record.id + '"] td[data-attribute="' + attributeName + '"]').text(newValue); } me.removeRecord = function(record) { $table.find('tr[data-id="' + record.id + '"]').fadeTo("slow", 0.7, function() { $(this).remove(); }); } }; })(); //Applicaton ajax wrapper function appAjax(processingMsg, ajaxOptions) { notificationMsg.show(processingMsg); return webapi.safeAjax(ajaxOptions) .fail(function(response) { if (response.responseJSON) { alert("Error: " + response.responseJSON.error.message) } else { alert("Error: Web API is not available... ") } }).always(notificationMsg.hide); } function loadRecords() { return appAjax('Loading...', { type: "GET", url: "/_api/contacts?$select=fullname,firstname,lastname,emailaddress1,telephone1", contentType: "application/json" }); } function addSampleRecord() { //Sample data to create a record - change as appropriate var recordObj = { firstname: "Willie", lastname: "Huff" + _.random(100, 999), emailaddress1: "Willie.Huff@contoso.com", telephone1: "555-123-4567" }; appAjax('Adding...', { type: "POST", url: "/_api/contacts", contentType: "application/json", data: JSON.stringify(recordObj), success: function(res, status, xhr) { recordObj.id = xhr.getResponseHeader("entityid"); recordObj.fullname = recordObj.firstname + " " + recordObj.lastname; table.addRecord(recordObj); } }); return false; } function deleteRecord(recordObj) { var response = confirm("Are you sure, you want to delete \"" + recordObj.name + "\" ?"); if (response == true) { appAjax('Deleting...', { type: "DELETE", url: "/_api/contacts(" + recordObj.id + ")", contentType: "application/json", success: function(res) { table.removeRecord(recordObj); } }); } return false; } function updateRecordAttribute(col, recordObj) { var attributeName = col.name, value = recordObj[attributeName], newValue = prompt("Please enter \"" + col.label + "\"", value); if (newValue != null && newValue !== value) { appAjax('Updating...', { type: "PUT", url: "/_api/contacts(" + recordObj.id + ")/" + attributeName, contentType: "application/json", data: JSON.stringify({ "value": newValue }), success: function(res) { table.updateRecord(attributeName, newValue, recordObj); } }); } return false; } var table = new webAPIExampleTable({ columns: [{ name: 'firstname', label: 'First Name', handler: updateRecordAttribute }, { name: 'lastname', label: 'Last Name', handler: updateRecordAttribute }, { name: 'emailaddress1', label: 'Email', handler: updateRecordAttribute }, { name: 'telephone1', label: 'Telephone', handler: updateRecordAttribute }], data: [], addHandler: addSampleRecord, deleteHandler: deleteRecord }); loadRecords().done(function(data) { table.data = _.map(data.value, function(record){ record.id = record.contactid; return record; }); table.render($('#dataTable')); }); }); </script> <div id="processingMsg" class="alert alert-warning" role="alert"></div> <div id="dataTable"></div>
選取儲存後關閉。
步驟 4: 清除入口網站快取
您已建立 webapi 範例頁面,以測試 Web API 功能。 開始使用之前,請確定已清除 Power Apps 入口網站快取,這樣入口網站管理應用程式的變更就會反映在您的入口網站上。
重要:,當資料從 Microsoft Dataverse 重新載入時,清除入口網站伺服器端快取將暫時導致入口網站效能下降。
清除快取:
以系統管理員 Web 角色的成員身分登入您的入口網站。
請在結尾附加 /_services/about 來變更 URL。 例如,如果入口網站 URL 是 https://contoso.powerappsportals.com,則將其變更為 https://contoso.powerappsportals.com/_services/about。
請注意: 您必須是 管理員 Web 角色的成員,才能清除快取。 如果您看到空白畫面,請檢查 Web 角色指派。
選取 清除快取。
其他資訊: 清除入口網站的伺服器端快取
步驟 5。 使用 Web API 讀取、查看、編輯、建立和刪除
之前建立的 URL webapi 的範例網頁現在已準備好進行測試。
若要測試 Web API 功能:
使用指派給您先前建立之 WEB API 使用者角色的使用者帳戶登入您的入口網站。
移至先前建立的 webapi 網頁。 例如:*https://contoso.powerappsportals.com/webapi*。 WebAPI 將從 Micrsoft Dataverse 中擷取記錄。
選取新增範例記錄,以透過指令碼新增範例記錄。
選取一個欄位。 在此範例中,我們選取電子郵件來變更連絡人的電子郵件地址。
選取 以刪除記錄。
現在,您已經建立一個包含讀取、編輯、建立和刪除記錄範例的網頁,您可以自訂表單和版面配置。
下一個步驟
請參閱
入口網站 Web API 概觀
入口網站使用 Web API 寫入、更新和刪除作業
使用 Web API 的入口網站讀取作業
設定資料行權限