POST 请求 SharePoint 列表:方法 GetByTitle 中不存在参数 __metadata

POST Request to SharePoint List: The parameter __metadata does not exist in method GetByTitle

我正在努力完成这个项目,但 运行 遇到了这个令人讨厌的错误。我在 MSDN、Stack Overflow 和许多其他网站上搜索了又搜索,但似乎找不到问题所在。我发现 post 有人面临与我相同的问题,他们说该解决方案有效,但它给了我与开始时相同的错误。然后,我找到了 this 但它并没有解决我的问题。

此 POST 请求的目的是从 HTML 表单收集 JSON 数据并将其发送到相应的 SharePoint 列表。将其发送到相应的 SharePoint 列表的目的是让我的 DataTable(在另一个子网站上)可以通过代码中较早的 GET 请求进行更新。我发现这种方式是更新 DataTable 的最简单途径。

这是完整的 error/alert(在 JSON 中):

{
  "readyState": 4,
  "responseText": "{\"error\":{\"code\":\"-1, Microsoft.SharePoint.Client.InvalidClientQueryException\",\"message\":{\"lang\":\"en-US\",\"value\":\"The parameter __metadata does not exist in method GetByTitle.\"}}}",
  "responseJSON": {
    "error": {
      "code": "-1, Microsoft.SharePoint.Client.InvalidClientQueryException",
      "message": {
        "lang": "en-US",
        "value": "The parameter __metadata does not exist in method GetByTitle."
      }
    }
  },
  "status": 400,
  "statusText": "error"
}

这是我的代码:

function loadData() { //Initializing the AJAX Request function to load in the external list data from different subsites
        //create an array of urls to run through the ajax request instead of having to do multiple AJAX Requests
        var urls = ["/items?$select=Program,Deliverable,To,Date,Approved,Notes",
       "/items?$select=Program,Deliverable,To,Date,Approved,Notes",
            "/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "/items?$select=Program,To,Date,Approved,Notes,Deliverable",
            "/items?$select=Program,To,Date,Approved,Notes,Deliverable"
        ];
    
        for (i = 0; i < urls.length; i++) { //for loop to run through the AJAX until all URLs have been reached
            $.ajax({
                url: urls[i],
                method: "GET",
                headers: {
                    "Accept": "application/json; odata=verbose"
                },
                success: function(data) { // success function which will then execute "GETTING" the data to post it to a object array (data.value)
                    console.log(data);
                    if (data.d != null && data.d != undefined && data.d.results.length > 0) {
                        var table = $('#myTable').DataTable();
                        table.rows.add(data.d.results).draw();
                    }
                }
            });
        }
    }
    
    $(document).ready(function() {
        var collapsedGroups = {};
        var top = '';
        var parent = '';
    
        var table = $('#myTable').DataTable({
        "pageLength" : 50,
            "columns": [{
                    "data": "Program",
                    visible: false
                },
                {
                    "data": "Deliverable",
                    visible: false
                },
                {
                    "data": "To"
                },
                {
                    "data": "Date"
                },
                {
                    "data": "Approved"
                },
                {
                    "data": "Notes"
                }
            ],
    
            dom: "<'row'<'col-sm-12 col-md-10'f><'col-sm-12 col-md-2'B>>" +
                "<'row'<'col-sm-12'tr>>" +
                "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>",
            buttons: [{
                extend: 'collection',
                className: "btn-dark",
                text: 'Export/Update Table',
                buttons: [{
                        extend: "excel",
                        className: "btn-dark"
                    },
                    {
                        extend: "pdf",
                        className: "btn-dark"
                    },
                    {
                        extend: "print",
                        className: "btn-dark"
                    },
                    {
                        text: 'Update Table',
                        action: function (e, dt, node, config){
                        $('#myModal').modal('show');
            }
        },
                ],
            }],
            order: [
                [0, 'asc'],
                [1, 'asc']
            ],
            rowGroup: {
                dataSrc: [
                    'Program',
                    'Deliverable'
                ],
                startRender: function(rows, group, level) {
                    var all;
                    if (level === 0) {
                        top = group;
                        all = group;
                    } else if (level === 1) {
                        parent = top + group;
                        all = parent;
                        // if parent collapsed, nothing to do
                        if (!collapsedGroups[top]) {
                            return;
                        }
                    } else {
                        // if parent collapsed, nothing to do
                        if (!collapsedGroups[parent]) {
                            return;
                        }
                        all = top + parent + group;
                    }
    
                    var collapsed = !collapsedGroups[all];
                    console.log('collapsed:', collapsed);
    
                    rows.nodes().each(function(r) {
                        r.style.display = collapsed ? 'none' : '';
                    });
                    //Add category name to the <tr>.
                    return $('<tr/>')
                        .append('<td colspan="8">' + group + ' (' + rows.count() + ')</td>')
                        .attr('data-name', all)
                        .toggleClass('collapsed', collapsed);
    
    
                }
    
            }
        });
    
        loadData();
    
        $('#myTable tbody').on('click', 'tr.dtrg-start', function() {
            var name = $(this).data('name');
            collapsedGroups[name] = !collapsedGroups[name];
            table.draw(false);
        });
    
        $("#btn").click(function(e) {
            PostItem();
        });
    });
    
       function PostItem() {
        return getFormDigest("").then(function(digestData) {
            console.log(digestData.d.GetContextWebInformation.FormDigestValue);
            $.ajax({
                async: true, // Async by default is set to “true” load the script asynchronously  
                // URL to post data into sharepoint list  or your own url
                url: "",
                method: "POST", //Specifies the operation to create the list item  
                data: JSON.stringify({ '__metadata': { 'type': 'SP.List' }, 'AllowContentTypes': true,
                'BaseTemplate': 100, 'ContentTypesEnabled': true, 'Description': 'My list description', 'Title': 'AMMO Deliverables' }
                ), 
            
                headers: {
                    "accept": "application/json;odata=verbose",
                    "content-type": "application/json;odata=verbose",
                    "X-RequestDigest": $("#__REQUESTDIGEST").val()
                },
                success: function(data) {
                    alert('Success'); // Used sweet alert for success message
                },
                error: function(error) {
                    alert(JSON.stringify(error));
                    console.log(JSON.stringify(error));

                }

            });
        })
    }
            function getItemTypeForListName(listName) {
                var itemType = "SP.Data." + listName.charAt(0).toUpperCase() + listName.slice(1) + "ListName";
                var encItemType = itemType.replace(/\s/g,'_x0020_');
                return(encItemType);
    }       
        function getFormDigest(siteurl) {
    
            return $.ajax({
    
                url: "",
    
                method: 'POST',
    
                headers: {
                    'Accept': 'application/json; odata=verbose'
                }
    
            });
            }   
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel ="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.css"/>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.flash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.2/js/buttons.print.min.js"></script>
<script src="https://cdn.datatables.net/rowgroup/1.1.2/js/dataTables.rowGroup.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.6.3/js/buttons.bootstrap4.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap4.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<link rel ="stylesheet" href="https://cdn.datatables.net/rowgroup/1.1.2/css/rowGroup.bootstrap4.min.css"/>
<link rel ="stylsheet" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap4.min.css"/>
<link rel ="stylesheet" href="https://cdn.datatables.net/buttons/1.6.3/css/buttons.bootstrap4.min.css"/>
<h1><strong>G3G Deliverables</strong></h1>
        <div class ="container">
            <table id="myTable" class="table table-bordered" cellspacing="0" width="100%">
                <thead class="thead-dark">
                    <tr>
                    <th>Program</th>
                    <th>Deliverable</th>
                    <th>To</th>
                    <th>Date</th>
                    <th>Approved</th>
                    <th>Notes</th>
                    </tr>
                </thead>
            </table>
            </div>
             <meta name="_csrf" content="${_csrf.token}"/>
        <meta name="_csrf_header" content="${_csrf.headerName}"/>
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel">Update DataTable</h4>
      </div>
      <div class="modal-body">
            <form id="myform" type="post" runat="server">
                <SharePoint:FormDigest ID="myForm" runat="server">
                <fieldset>
                    <legend align="center">Update Datatable</legend>
                    <p>Please fill out the shown fields to add data to the DataTable</p>
                    <div class="elements">
                    <label for="program">Program :</label>
                    <select name = "program" id="dProgram">
                            <option value = "AHR">AHR</option>
                            <option value = "AMMO">AMMO</option>
                            <option value = "DAR-Q">DAR-Q</option>
                            <option value = "Doctrine Development">Doctrine Development</option>
                            <option value = "Operational Energy">Operational Energy</option>
                            <option value = "Ordnance Multimedia">Ordnance Multimedia</option>
                            <option value = "SRC Handbook">SRC Handbook</option>
                            <option value = "WTBn">WTBn</option>
                        </select>
                    </div>
                    <div class="elements">
                    <label for="Deliverable">Deliverable :</label>
                    <select name="Deliverable" id="dDeliverable">
                            <option value = "Meeting Minutes">Meeting Minutes</option>
                            <option value = "Monthly Status Report (MSR)">Monthly Status Report (MSR)</option>
                            </select>
                    </div>  
                    <div class="elements">
                    <label for="To"> To:</label>
                    <input type="text" align= "center" id="dTo" name="To" placeholder="example@example.com">
                    </div>      
                    <div class="elements">
                    <label for="Date">Date: </label>
                    <input type="date" align= "center" id="dDate" name="Date" placeholder="MM/DD/YYYY"> 
                    </div>  
                    <div class="elements">
                    <label for="Approved">Approved :</label>
                    <select name="Approved" id="dApproved">
                            <option value = "True">Yes</option>
                        <option value = "False">No</option></select>
                    </div>  
                    <div class="elements">
                    <label for="Notes"> Notes :</label>
                    <input type="text" align= "left" id="dNotes" name="Notes" placeholder="Please provide notes">
                </div>
                <div class="submit">
                    <input type="submit" id="btn" name="btn" class="btn" value="Submit" />
                    </div>
                </fieldset>
                </SharePoint:FormDigest>
            </form>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<style>
这是更新我的代码后抛出的新错误:

{
  "readyState": 4,
  "responseText": "{\"error\":{\"code\":\"-2130575251, Microsoft.SharePoint.SPException\",\"message\":{\"lang\":\"en-US\",\"value\":\"The security validation for this page is invalid and might be corrupted. Please use your web browser's Back button to try your operation again.\"}}}",
  "responseJSON": {
    "error": {
      "code": "-2130575251, Microsoft.SharePoint.SPException",
      "message": {
        "lang": "en-US",
        "value": "The security validation for this page is invalid and might be corrupted. Please use your web browser's Back button to try your operation again."
      }
    }
  },
  "status": 403,
  "statusText": "error"
}

更新:

这是我对代码所做的以下更改(它会产生相同的 403 错误):

function PostItem() {
            return getFormDigest(" ").then(function(digestData) {
                console.log(digestData.d.GetContextWebInformation.FormDigestValue);
                $.ajax({
                type: 'POST',
                url: "",
                dataType: 'json',
                data: JSON.stringify({
                    "__metadata": { "type": "SP.Data.DeliverablesListItem" },
                    "Program": dProgram,
                    "Deliverable": dDeliverable,
                    "To": dTo,
                    "Date": dDate,
                    "Approved": dApproved,
                    "Notes": dNotes
                }),
                headers: {
                    "Accept": "application/json; odata=verbose",
                    "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                    'content-type': 'application/json;odata=verbose',
                    'X-HTTP-Method': 'MERGE',
                    'if-match': '*'
                },
                success: function (data) {
                    alert('player updated');
                },
                error: function (msg) {
                    alert(msg.responseText);
                    console.log(msg);
                }

            }); 
            })
        }

错误告诉你getbytitle

上没有__metdata属性

The parameter __metadata does not exist in method GetByTitle.

您应该能够更改 url 属性 以摆脱 url.

中的 getbytitle 参数

示例:

jQuery.ajax({
        url: "http://<site url>/_api/web/lists",
        type: "POST",
        data:  JSON.stringify({ '__metadata': { 'type': 'SP.List' }, 'AllowContentTypes': true,
 'BaseTemplate': 100, 'ContentTypesEnabled': true, 'Description': 'My list description', 'Title': 'Test' }
),
        headers: {
            "accept": "application/json;odata=verbose",
            "content-type": "application/json;odata=verbose",
            "content-length": <length of post body>,
            "X-RequestDigest": $("#__REQUESTDIGEST").val()
        },
        success: doSuccess,
        error: doError
});

更新:

我找到了我的一个旧示例,发现了几个问题:

  1. __metdata 中的 SP.List 需要替换为特定的 SP.List 类型。 (见下面的例子)
  2. 您需要提供 etag 信息(参见下面的示例)

这是我更新 SP 列表的旧示例

$.ajax({
                type: 'POST',
                url: uri,
                dataType: 'json',
                data: JSON.stringify({
                    "__metadata": { "type": "SP.Data.Seahawks_x0020_RosterListItem" },
                    "Title": newPlayer.name,
                    "Jersey_x0020_Number": newPlayer.jerseyNumber,
                    "Position": newPlayer.position,
                    "Height": newPlayer.height,
                    "Weight": newPlayer.weight,
                    "Age": newPlayer.age,
                    "Years_x0020_of_x0020_Experience": newPlayer.yoe,
                    "College": newPlayer.college
                }),
                headers: {
                    "Accept": "application/json; odata=verbose",
                    "X-RequestDigest": $("#__REQUESTDIGEST").val(),
                    'content-type': 'application/json;odata=verbose',
                    'X-HTTP-Method': 'MERGE',
                    'if-match': etag
                },
                success: function (data) {
                    that.loadRoster();
                    alert('player updated');
                },
                error: function (msg) {
                    alert(msg.responseText);
                    console.log(msg);
                }

            }); 

这是获取 etag

的逻辑
getItemId: function (title, callback) {
        $.ajax({
            type: 'GET',
            url: "https://site.sharepoint.com/_api/lists/GetByTitle('Seahawks%20Roster')/items",
            dataType: 'json',
            body: JSON.stringify({
                "__metadata": { "type": "SP.Data.Seahawks_x0020_RosterListItem" },
                "Title": title
            }),
            headers: {
                "Accept": "application/json; odata=verbose",
                "X-RequestDigest": $("#__REQUESTDIGEST").val()
            },
            success: function (data) {

                for (var i = 0; i < data.d.results.length; i++) {

                    var name = data.d.results[i].Title;

                    if (name == title) {
                        callback(data.d.results[i].Id, data.d.results[i].__metadata.etag, data.d.results[i].__metadata.uri);
                        break;
                    }
                }
            },
            error: function (msg) {
                alert(msg.responseText);
                console.log(msg);
            }

        });

    },

这里还有一些 SP 的 REST 操作示例:https://docs.microsoft.com/en-us/sharepoint/dev/sp-add-ins/complete-basic-operations-using-sharepoint-rest-endpoints