【问题标题】:REST calls vs. JSOM calls from a sandbox solution to a SharePoint 2013 Site从沙盒解决方案到 SharePoint 2013 站点的 REST 调用与 JSOM 调用
【发布时间】:2021-05-03 05:54:15
【问题描述】:

我有一个 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);
    });

}

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

在此先感谢您的阅读!

【问题讨论】:

    标签: angular sharepoint sharepoint-jsom sharepoint-rest-api


    【解决方案1】:

    你能不能改变下面这一行,这样父项 id 就不会被忽略了

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

    【讨论】:

    • 问题是我想设置 parentId,但显然专门针对讨论列表,这是一个无法通过 REST 调用以任何方式设置的只读字段
    【解决方案2】:

    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

    【讨论】:

    • 感谢您的评论,我会尝试一下。我实际上已经看到了您提出的链接,但是当人们尝试通过 REST API 创建讨论时,它经常会出现一条评论:“虽然这似乎有效(回复显示在父帖子的讨论线程中)它没有在回复上设置 ParentItemID 属性,它保持为空,这破坏了讨论的一些功能。请参阅这篇文章了解原因:REST api support for discussion list"。您的解决方案仍然看起来略有不同(特别是对于有效负载的管理方式)。我会检查它是否有效。
    • 不幸的是,我的结果是一样的,ParentId 没有以这种方式设置,即使您能够更改项目的文件夹,如果没有 ParentId,线程功能也会丢失。
    猜你喜欢
    • 2013-12-02
    • 2011-08-09
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 2011-11-20
    • 2015-05-07
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多