วิธีการ: โต้ตอบกับตาราง Dataverse โดยใช้ตรรกะของเซิร์ฟเวอร์

ในคู่มือนี้ คุณจะตั้งค่าเว็บเพจและเทมเพลตเว็บแบบกําหนดเองที่จะใช้ตรรกะของเซิร์ฟเวอร์ในการอ่าน เขียน อัปเดต และลบเรกคอร์ดจากตารางผู้ติดต่อ

ขั้นตอนที่ 1: สร้างตรรกะเซิร์ฟเวอร์

  1. ลงชื่อเข้าใช้ Power Pages

  2. เลือกไซต์ + แก้ไข

  3. นําทางไปยังตั้งค่าพื้นที่ทํางาน จากนั้นเลือกตรรกะเซิร์ฟเวอร์ (ตัวอย่าง)

  4. เลือก +ตรรกะเซิร์ฟเวอร์ใหม่

  5. ป้อนชื่อสําหรับตรรกะของเซิร์ฟเวอร์ ชื่อนี้ถูกใช้ใน API เป็นตัวระบุทรัพยากรขณะสร้าง API ตรรกะของเซิร์ฟเวอร์

    ตัวอย่าง: dataverse-crud-operations

  6. เลือก +เพิ่มบทบาท เพื่อกําหนดบทบาทของเว็บที่เหมาะสม

  7. เลือก 3 จุด (...) ที่อยู่ถัดจากชื่อ และเลือก แก้ไขโค้ด

  8. เลือก เปิดรหัส Visual Studio เพื่อเขียนตรรกะแบบกําหนดเอง คุณจะพบวิธีการและสคริปต์ที่กําหนดไว้ล่วงหน้าในไฟล์

  9. กําหนดวิธีตรรกะของเซิร์ฟเวอร์สําหรับอ่าน แก้ไข สร้าง ลบเรกคอร์ดผู้ติดต่อ

    อ่าน: เพิ่มสคริปต์ที่อยู่ด้านล่างภายในวิธีการ 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);
    }
    

    สร้าง: เพิ่มสคริปต์ด้านล่างในวิธีการโพสต์

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

    อัปเดต: เพิ่มสคริปต์ด้านล่างในเมธอด put

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

    ลบ: เพิ่มภายในวิธีการ 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. บันทึกไฟล์

  11. นี่คือรหัสตรรกะของเซิร์ฟเวอร์ที่สมบูรณ์ที่สามารถวางได้

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

ขั้นตอนที่ 2: สร้างเว็บเพจ

  1. เปิดใช้สตูดิโอออกแบบ Power Pages

  2. ในพื้นที่ทํางานของหน้า ให้เลือก+ หน้า

  3. ในกล่องโต้ตอบ เพิ่มหน้า ให้ใส่ ตรรกะของเซิร์ฟเวอร์ ในกล่อง ชื่อ และเลือก เริ่มต้นจากเค้าโครงว่างเปล่า

  4. เลือก เพิ่ม

  5. เลือกตัวเลือก แก้ไขรหัส ที่มุมขวาบน

  6. เลือกเปิด Visual Studio Code

  7. คัดลอกส่วนย่อยของโค้ดตัวอย่างต่อไปนี้และวางไว้ระหว่าง <div></div> แท็กของส่วนหน้า

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

ขั้นตอนที่ 3: กําหนดค่าสิทธิ์

สร้างบทบาทเว็บ

ถ้าคุณยังไม่มีบทบาทเว็บที่มีสิทธิ์ในตารางที่คุณกําลังเข้าถึงผ่านตรรกะเซิร์ฟเวอร์ หรือจําเป็นต้องมีบริบทที่แตกต่างกันของการเข้าถึงข้อมูล ขั้นตอนต่อไปนี้แสดงวิธีการสร้างบทบาทเว็บใหม่และกําหนดสิทธิ์ตาราง

  1. เริ่มใช้งานPortal Management app
  2. ในบานหน้าต่างด้านซ้าย ในส่วนความปลอดภัย ให้เลือกบทบาทเว็บ
  3. เลือก ใหม่
  4. ในกล่อง ชื่อ ให้ป้อน ผู้ใช้ตรรกะของเซิร์ฟเวอร์ (หรือชื่อใด ๆ ที่แสดงถึงบทบาทของผู้ใช้ในการเข้าถึงฟังก์ชันนี้ที่ดีที่สุด)
  5. ในรายการ เว็บไซต์ ให้เลือกระเบียนเว็บไซต์ของคุณ
  6. เลือก บันทึก

สร้างสิทธิ์ของตาราง

  1. เปิดใช้สตูดิโอออกแบบ Power Pages
  2. เลือกพื้นที่ทํางานความปลอดภัย
  3. ภายใต้ส่วน ป้องกัน ให้เลือก สิทธิ์ตาราง
  4. เลือก สิทธิ์ใหม่
  5. ในกล่องชื่อ ให้ใส่ สิทธิ์ตารางผู้ติดต่อ
  6. ในรายการ ชื่อตาราง ให้เลือก ผู้ติดต่อ (ผู้ติดต่อ)
  7. ในรายการประเภทการเข้าถึง เลือกส่วนกลาง
  8. เลือก อ่านเขียนสร้าง และ ลบ สิทธิ์
  9. เลือก + เพิ่มบทบาท และเลือก บทบาทของเว็บ ที่คุณเลือกหรือสร้างไว้ก่อนหน้านี้
  10. เลือก บันทึก & ปิด

เพิ่มผู้ติดต่อให้กับบทบาทเว็บ

  1. เปิดใช้ แอปจัดการพอร์ทัล
  2. ในบานหน้าต่างด้านซ้าย ในส่วนความปลอดภัย ให้เลือกผู้ติดต่อ
  3. เลือกผู้ติดต่อที่คุณต้องการใช้ในตัวอย่างนี้สําหรับตรรกะเซิร์ฟเวอร์

    Note

    ผู้ติดต่อนี้คือบัญชีผู้ใช้ที่ใช้ในตัวอย่างนี้สําหรับการทดสอบตรรกะของเซิร์ฟเวอร์ ตรวจสอบให้แน่ใจว่าได้เลือกผู้ติดต่อที่ถูกต้องในพอร์ทัลของคุณ

  4. เลือกบทบาทเว็บ>
  5. เลือกเพิ่มบทบาทเว็บที่มีอยู่
  6. เลือกบทบาท ผู้ใช้เชิงตรรกะของเซิร์ฟเวอร์ ที่สร้างขึ้นก่อนหน้านี้
  7. เลือก เพิ่ม
  8. เลือก บันทึก & ปิด

ขั้นตอนที่ 4: ใช้ตรรกะเซิร์ฟเวอร์เพื่ออ่าน ดู แก้ไข สร้าง และลบ

หากต้องการทดสอบฟังก์ชันการทํางานของ API เว็บ:

  1. เลือกแสดงตัวอย่าง แล้วเลือกเดสก์ท็อป
  2. ลงชื่อเข้าใช้ไซต์ของคุณด้วยบัญชีผู้ใช้ที่ได้รับการกําหนดบทบาท ผู้ใช้เชิงตรรกะของเซิร์ฟเวอร์ ที่คุณสร้างไว้ก่อนหน้านี้
  3. ไปยังเว็บเพจ ตรรกะของเซิร์ฟเวอร์ ที่สร้างไว้ก่อนหน้านี้

ภาพรวมตรรกะของเซิร์ฟเวอร์
ตรรกะของเซิร์ฟเวอร์ผู้เขียน
วัตถุเซิร์ฟเวอร์