0

我有一个 Angular 2+ 应用程序,它通过 REST API 愉快地执行对托管在不同服务器中的 SharePoint 2013 的调用。它工作得很好,但不幸的是,对于一个非常特殊的需求(讨论板)来说,这还不够。这是我在做什么:

async addMessageREST(callback, siteUrl, discussionBoardName, parentItemId, newMessageBody) {

    const requestOptions = {
      withCredentials: true,
      crossDomain: true
    };

    var messagePayload = {
      // '__metadata': { "type": "SP.Data.DiscussionsListItem" },
      'Body': newMessageBody,  
      'ParentItemID': parentItemId, //unfortunately will be ignored
      'FileSystemObjectType': 0,
      'ContentTypeId': '0x0107008822E9328717EB48B3B665EE2266388E'
    };

    // retrieve the contextinfo
    let contextinfo = await this._http
    .post(
          siteUrl + '/_api/contextinfo',
          null,
          requestOptions
    )
    .toPromise();

    // finally post the request
    const requestOptionsAddMessage = {
    withCredentials: true,
    crossDomain: true,
    headers: new HttpHeaders().set('X-RequestDigest', contextinfo["FormDigestValue"]).set("Accept", "application/json;odata=verbose")
    };

    let request = "/_api/web/Lists/GetByTitle('" + discussionBoardName + "')/items";


    let discussionItem = await this._http
    .post(
    siteUrl + request,
    messagePayload,
    requestOptionsAllMessages
  )
  .toPromise();

callback(discussionItem);
}

从技术上讲,这很好用,但不幸的是,这还不够,因为您可能知道 REST API 不提供特定功能来管理讨论项。为此 JSOM 提供了相当不错的方法,但不幸的是我无法与它建立连接(我收到 401 错误)。这是我在做什么:

addMessageJSOM(callback, siteUrl, discussionBoardName, parentTopicId, newMessageBody) {

    let clientContext = new SP.ClientContext(siteUrl);

    let list = clientContext.get_web().get_lists().getByTitle(discussionBoardName);
    
    let discussionItem = list.getItemById(parentTopicId);

    let properties = {
       'Body': newMessageBody
    };

    let messageItem = SP.Utilities.Utility.createNewDiscussionReply(clientContext, discussionItem);

    for (var propName in properties) {
      messageItem.set_item(propName, properties[propName])
    }
    messageItem.update();

    clientContext.executeQueryAsync(() => {
      callback(messageItem);
    }, (error: any) => {
        console.log('Request failed', error);
    });

}

一切正常,直到涉及到 executeQueryAsync,我得到了 401 错误。我想这是因为不知何故我没有在 REST 调用中传递我通过 HTTP 传递的摘要/选项。知道如何通过 JSOM 传递这些选项吗?或者,有一种方法可以通过 HTTP 调用 JSOM 端点而不依赖于 SP 库?

在此先感谢您的阅读!

4

2 回答 2

0

您可以更改以下行,以便不会忽略父项 id

let request = "/_api/web/Lists/GetByTitle('" + discussionBoardName + "')/items(" + parentItemId + ")" ;
于 2021-01-29T14:36:55.617 回答
0

JSOM 必须依赖于 SP 库。如果你想通过 Rest API 创建讨论项,你可以参考下面的 demo:

function executeJson(options) {
    var headers = options.headers || {};
    var method = options.method || "GET";
    headers["Accept"] = "application/json;odata=verbose";
    if (options.method == "POST") {
        headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();
    }

    var ajaxOptions =
    {
        url: options.url,
        type: method,
        contentType: "application/json;odata=verbose",
        headers: headers
    };
    if ("data" in options) {
        ajaxOptions.data = JSON.stringify(options.data);
    }

    return $.ajax(ajaxOptions);
}


function createListItem(webUrl, listTitle, payload) {
    var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/items";
    return executeJson({
        "url": url,
        "method": 'POST',
        "data": payload
    });
}

function moveListItem(webUrl, listTitle, itemId, folderUrl) {
    var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/getItemById(" + itemId + ")?$select=FileDirRef,FileRef";
    return executeJson({
        "url": url
    })
        .then(function (result) {
            var fileUrl = result.d.FileRef;
            var fileDirRef = result.d.FileDirRef;
            var moveFileUrl = fileUrl.replace(fileDirRef, folderUrl);
            var url = webUrl + "/_api/web/getfilebyserverrelativeurl('" + fileUrl + "')/moveto(newurl='" + moveFileUrl + "',flags=1)";
            return executeJson({
                "url": url,
                "method": 'POST'
            });
        });
}


function getParentTopic(webUrl, listTitle, itemId) {
    var url = webUrl + "/_api/web/lists/getbytitle('" + listTitle + "')/getItemById(" + itemId + ")/Folder";
    return executeJson({
        "url": url,
    });
}


function createNewDiscussionReply(webUrl, listTitle, messagePayload) {
    var topicUrl = null;
    return getParentTopic(webUrl, listTitle, messagePayload.ParentItemID)
        .then(function (result) {
            topicUrl = result.d.ServerRelativeUrl;
            return createListItem(webUrl, listTitle, messagePayload);
        })
        .then(function (result) {
            var itemId = result.d.Id;
            return moveListItem(webUrl, listTitle, itemId, topicUrl);
        });
}

$(function () {
    // Handler for .ready() called.

    var listTitle = "discuss";
    var webUrl = _spPageContextInfo.webAbsoluteUrl;
    var messagePayload = {
        '__metadata': { "type": "SP.Data.DiscussListItem" },  //set DiscussionBoard entity type name
        'Body': "Thanks for the information",  //message Body
        'FileSystemObjectType': 0, //setto 0 to make sure Mesage Item
        'ContentTypeId': '0x0107008822E9328717EB48B3B665EE2266388E', //set Message content type
        'ParentItemID': 1  //set Discussion (topic) Id
    };

    createNewDiscussionReply(webUrl, listTitle, messagePayload)
        .done(function (item) {
            console.log('Message(reply) has been sent');
        })
        .fail(function (error) {
            console.log(JSON.stringify(error));
        });

});

更多参考:

BR

于 2021-02-01T06:04:05.317 回答