在 SharePoint 中使用 JavaScript 对象模型创建和删除帖子并检索社交源

了解如何使用 SharePoint JavaScript 对象模型创建和删除微博帖子,并检索社交源。

什么是 SharePoint 中的社交源?

在 SharePoint 中,社交源是一组表示对话、各篇微博帖子或通知的线程。 线程包含根帖子和一组回复帖子。 在 JavaScript 对象模型中,源由 SocialFeed 对象表示,线程由 SocialThread 对象表示,帖子和答复由 SocialPost 对象表示。 若要执行与源相关的核心任务,请使用 SocialFeedManager 对象。 本文将介绍如何创建应用页,以便使用 JavaScript 对象模型处理社交源。

有关使用 SocialFeedManager 的详细信息或有关使用其他 API 处理社交源的信息,请参阅 在 SharePoint 中使用社交源

为了使用 SharePointJavaScript 对象模型中的好友动态订阅源而设置开发坏境的先决条件

若要创建使用 JavaScript 对象模型处理社交源的应用页,需要满足以下条件:

  • SharePoint 配置有“我的网站”作为公共网站,并为当前用户和目标用户创建了个人网站,同时当前用户关注目标用户,且目标用户撰写了几篇帖子

  • Visual Studio 2012 或 Visual Studio 2013(带 Visual Studio 2013 的 Office 开发人员工具)

  • "完全控制"针对 User Profile Service 应用程序的访问权限和为已登录用户部署场解决方案的权限

  • 应用程序池帐户用于访问"我的网站"网络应用程序内容数据库的充足访问权限

通过使用 SharePoint JavaScript 对象模型创建使用好友动态订阅源的应用程序页

  1. 打开 Visual Studio,依次选择"文件"、"新建"、"项目"。

  2. 在"新建项目"对话框中,从对话框顶部的下拉列表中选择".NET Framework 4.5"。

  3. 在"模版"列表中,展开"Office SharePoint",选择"SharePoint 解决方案"类别,然后选择"SharePoint 项目"模板。

  4. 将项目命名为 SocialFeedJSOM,然后选择"确定"按钮。

  5. 在"SharePoint 自定义向导"对话框中,选择"部署场解决方案",然后选择"完成"按钮。

  6. 在"解决方案资源管理器"中,打开 SocialFeedJSOM 项目的快捷菜单,然后添加 SharePoint"布局"映射文件夹。

  7. 在“布局”文件夹中,打开“SocialFeedJSOM”文件夹的快捷菜单,再添加名为“SocialFeed.aspx”的新 SharePoint 应用页。

注意:本文中的代码示例在页面标记中定义了自定义代码,但没有使用 Visual Studio 为页面创建的代码隐藏类。

  1. 打开“SocialFeed.aspx”页的快捷菜单,再选择“设置为启动项”

  2. 在“SocialFeed.aspx”页的标记中,定义“主要”asp:Content 标记内的控件,如下面的代码所示。

<table width="100%" id="tblPosts"></table><br/>
<button id="btnDelete" type="button"></button><br />
<span id="spanMessage" style="color: #FF0000;"></span>

注意:这些控件可能并不适用于所有方案。 例如,“发布帖子和回复”方案只使用 span 控件。

  1. 在结束 范围 标记后,添加 SharePoint:ScriptLink 控件、 SharePoint:FormDigest 控件和 脚本 标记,如以下代码所示。 SharePoint:ScriptLink 标记引用类库文件,这些文件定义可用于“我的网站社交”开发的 JavaScript 对象模型。 如果更新服务器内容的操作需要,SharePoint:FormDigest 标记将为安全验证生成一个哈希。
<SharePoint:ScriptLink ID="ScriptLink1" name="SP.js" runat="server" ondemand="false" localizable="false" loadafterui="true" />
<SharePoint:ScriptLink ID="ScriptLink2" name="SP.UserProfiles.js" runat="server" ondemand="false" localizable="false" loadafterui="true" />
<SharePoint:FormDigest id="FormDigest" runat="server"/>
<script type="text/javascript">
    // Replace this comment with the code for your scenario.
</script>
  1. 若要添加逻辑以使用订阅源,请替换 script 标记和以下某一应用场景中的代码示例间的注释。
  1. 若要测试该应用程序页,请在菜单栏选择"调试"和"开始调式"。 如果您试图修改 web.config 文件,请选择"确定"按钮。

如果响应调用失败回调方法,在该方法中设置一个断点,然后添加对 args 对象的监视或查阅 ULS 日志和事件查看器,以获取更多信息。

代码示例:通过使用 SharePointJavaScript 对象模型发布文章和回复到好友动态

以下代码示例发布了一篇文章和一条回复。 它演示了如何:

  • 定义文章内容。 此示例包括了该文章中的一个链接。

  • 通过使用 createPost 方法并将 null 作为 targetId 参数进行传递以发布文章到当前用户的动态。

  • 使用 createPost 方法,并将线程标识符作为 targetId 参数传递,从而回复帖子。

注意

在通过创建应用页过程添加的 script 标记间粘贴下面的代码。

// Ensure that the SP.UserProfiles.js file is loaded before the custom code runs.
SP.SOD.executeOrDelayUntilScriptLoaded(PublishPost, 'SP.UserProfiles.js');

// Declare global variables.
var clientContext;
var feedManager;
var resultThread;

function PublishPost() {

    // Initialize the current client context and the SocialFeedManager instance.
    clientContext = SP.ClientContext.get_current();
    feedManager = new SP.Social.SocialFeedManager(clientContext);

    // Create a link to include in the post.
    var linkDataItem = new SP.Social.SocialDataItem();
    linkDataItem.set_itemType(SP.Social.SocialDataItemType.link);
    linkDataItem.set_text('link');
    linkDataItem.set_uri('http://bing.com');
    var socialDataItems = [ linkDataItem ];

    // Create the post content.
    var postCreationData = new SP.Social.SocialPostCreationData();
    postCreationData.set_contentText('The text for the post, which contains a {0}.');
    postCreationData.set_contentItems(socialDataItems);

    // Publish the post. Pass null for the "targetId" parameter because this is a root post.
    resultThread = feedManager.createPost(null, postCreationData);
    clientContext.executeQueryAsync(PublishReply, PostFailed);
    }
function PublishReply(sender, args) {

    // Create the reply content.
    var postCreationData = new SP.Social.SocialPostCreationData();
    postCreationData.set_contentText('The text for the reply.');

    // Publish the reply.
    resultThread = feedManager.createPost(resultThread.get_id(), postCreationData);
    clientContext.executeQueryAsync(PostSucceeded, PostFailed);
}
function PostSucceeded(sender, args) {
    $get("spanMessage").innerText = 'The post and reply were published.';
}
function PostFailed(sender, args) {
    $get("spanMessage").innerText = 'Request failed: ' + args.get_message();
}

代码示例:使用 SharePoint JavaScript 对象模型检索社交源

以下代码示例检索了当前用户和目标用户的动态。 它演示了如何:

  • 使用 getFeed 方法获得当前用户的 PersonalNewsTimeline 动态类型。

  • 使用 getFeedFor 方法获得目标用户的 Personal 动态类型。

  • 循环访问动态以查找所有非引用线索并获取有关线索和文章的信息。 引用线索表示包含有关另一个线索的信息的通知。 例如,如果用户在帖子中提到某人,则服务器将生成包含指向原帖和帖子其他元数据的链接的 MentionReference 类型的线索。

有关源类型的详细信息,请参阅 “我的网站社交 API”中的源类型概述。 有关引用线程的详细信息,请参阅 引用 SharePoint 社交源中的线程和摘要线程

注意

在通过创建应用页过程添加的 script 标记间粘贴下面的代码。 然后在运行代码之前,请先更改 targetUser 变量的占位符值。

// Replace the placeholder value with the account name of the target user.
var targetUser = 'domainName\\\\userName';

// Ensure that the SP.UserProfiles.js file is loaded before the custom code runs.
SP.SOD.executeOrDelayUntilScriptLoaded(GetFeeds, 'SP.UserProfiles.js');

// Declare global variables.
var clientContext;
var feedManager;
var personalFeed;
var newsFeed;
var timelineFeed;
var targetUserFeed;

function GetFeeds() {

    // Initialize the current client context and the SocialFeedManager instance.
    clientContext = SP.ClientContext.get_current();
    feedManager = new SP.Social.SocialFeedManager(clientContext);

    // Set parameters for the feed content that you want to retrieve.
    var feedOptions = new SP.Social.SocialFeedOptions();
    feedOptions.set_maxThreadCount(10); // default is 20

    // Get all feed types for current user and get the Personal feed
    // for the target user.
    personalFeed = feedManager.getFeed(SP.Social.SocialFeedType.personal, feedOptions);
    newsFeed = feedManager.getFeed(SP.Social.SocialFeedType.news, feedOptions);
    targetUserFeed = feedManager.getFeedFor(targetUser, feedOptions);

    // Change the sort order to optimize the Timeline feed results.
    feedOptions.set_sortOrder(SP.Social.SocialFeedSortOrder.byCreatedTime); 
    timelineFeed = feedManager.getFeed(SP.Social.SocialFeedType.timeline, feedOptions);

    clientContext.load(feedManager);
    clientContext.executeQueryAsync(CallIterateFunctionForFeeds, RequestFailed);
}
function CallIterateFunctionForFeeds() {
    IterateThroughFeed(personalFeed, "Personal", true);
    IterateThroughFeed(newsFeed, "News", true);
    IterateThroughFeed(timelineFeed, "Timeline", true); 
    IterateThroughFeed(targetUserFeed, "Personal", false);
}
function IterateThroughFeed(feed, feedType, isCurrentUser) {
    tblPosts.insertRow().insertCell();
    var feedHeaderRow = tblPosts.insertRow();
    var feedOwner = feedManager.get_owner().get_name();

    // Iterate through the array of threads in the feed.
    var threads = feed.get_threads();
    for (var i = 0; i < threads.length ; i++) {
        var thread = threads[i];
        var actors = thread.get_actors();

        if (i == 0) {

            // Get the name of the target user for the feed header row. Users are 
            // owners of all threads in their Personal feed.
            if (!isCurrentUser) {
                feedOwner = actors[thread.get_ownerIndex()].get_name();
            }
            feedHeaderRow.insertCell().innerText = feedType.toUpperCase() + ' FEED FOR '
                + feedOwner.toUpperCase();
        }

        // Use only Normal-type threads and ignore reference-type threads. (SocialThreadType.Normal = 0)
        if (thread.get_threadType() == 0) {

            // Get the root post's author, content, and number of replies.
            var post = thread.get_rootPost();
            var authorName = actors[post.get_authorIndex()].get_name();
            var postContent = post.get_text();
            var totalReplies = thread.get_totalReplyCount();

            var postRow = tblPosts.insertRow();
            postRow.insertCell().innerText = authorName + ' posted \\"' + postContent
                + '\\" (' + totalReplies + ' replies)';

            // If there are any replies, iterate through the array and
            // get the author and content. 
            // If a thread contains more than two replies, the server
            // returns a thread digest that contains only the two most
            // recent replies. To get all replies, call the 
            // SocialFeedManager.getFullThread method.
            if (totalReplies > 0) {
                var replies = thread.get_replies();

                for (var j = 0; j < replies.length; j++) {
                    var replyRow = tblPosts.insertRow();

                    var reply = replies[j];
                    replyRow.insertCell().innerText = '  - ' + actors[reply.get_authorIndex()].get_name()
                        + ' replied \\"' + reply.get_text() + '\\"';
                }
            }
        }
    }
}
function RequestFailed(sender, args) {
    $get("spanMessage").innerText = 'Request failed: ' + args.get_message();
}

代码示例:使用 SharePoint JavaScript 对象模型从社交源中删除帖子和回复

以下代码示例将删除文章或回复。 它演示了如何:

  • 使用 News 方法获得当前用户的 getFeed 动态类型。

  • 循环访问动态中的文章和回复以获取您用于删除文章或回复的 id 属性。

  • 使用 deletePost 方法删除根帖子或回复(删除根帖子会删除整个线程)。

注意

在通过创建应用页过程添加的 script 标记间粘贴下面的代码。 此示例假设当前用户的新闻源包含了至少一条帖子。

// Ensure that the SP.UserProfiles.js file is loaded before the custom code runs.
SP.SOD.executeOrDelayUntilScriptLoaded(GetFeeds, 'SP.UserProfiles.js');

// Declare global variables.
var clientContext;
var feedManager;
var feed;
var postOrReplyToDelete;

function GetFeeds() {

    // Initialize the current client context and the SocialFeedManager instance.
    clientContext = SP.ClientContext.get_current();
    feedManager = new SP.Social.SocialFeedManager(clientContext);

    // Set parameters for the feed content that you want to retrieve.
    var feedOptions = new SP.Social.SocialFeedOptions();
    feedOptions.set_maxThreadCount(10); // default is 20

    // Get all the News feed type for current user.
    feed = feedManager.getFeed(SP.Social.SocialFeedType.news, feedOptions);
    clientContext.executeQueryAsync(IterateThroughFeed, RequestFailed);
}
function IterateThroughFeed() {

    // Iterate through the array of threads in the feed.
    var threads = feed.get_threads();
    for (var i = 0; i < threads.length ; i++) {
        var thread = threads[i];
        var actors = thread.get_actors();

        // Get the root post's author, content, and number of replies.
        var post = thread.get_rootPost();

        var authorName = actors[post.get_authorIndex()].get_name();
        var postContent = post.get_text();
        var totalReplies = thread.get_totalReplyCount();

        var postRow = tblPosts.insertRow();
        postRow.insertCell().innerText = authorName + ' posted \\"' + postContent
            + '\\" (' + totalReplies + ' replies)';
        postOrReplyToDelete = post.get_id();

        // If there are any replies, iterate through the array and
        // get the author and content.
            // If a thread contains more than two replies, the server
            // returns a thread digest that contains only the two most
            // recent replies. To get all replies, call the 
            // SocialFeedManager.getFullThread method.
        if (totalReplies > 0) {
            var replies = thread.get_replies();
            for (var j = 0; j < replies.length; j++) {
                var replyRow = tblPosts.insertRow();

                var reply = replies[j];
                replyRow.insertCell().innerText = '  - ' + actors[reply.get_authorIndex()].get_name()
                    + ' replied \\"' + reply.get_text() + '\\"';
                postOrReplyToDelete = reply.get_id();
            }
        }

        // Initialize button properties.
        $get("btnDelete").onclick = function () { DeletePostOrReply(); };
        $get("btnDelete").innerText = 'Click to delete the last post or reply';
    }
}

// Delete the last post or reply listed on the page.
function DeletePostOrReply() {
    feedManager.deletePost(postOrReplyToDelete);
    clientContext.executeQueryAsync(DeleteSucceeded, RequestFailed);
}
function DeleteSucceeded(sender, args) {
    $get("spanMessage").innerText = 'The post or reply was deleted. Refresh the page to see your changes.';
}
function RequestFailed(sender, args) {
    $get("spanMessage").innerText = 'Request failed: ' + args.get_message();
}

另请参阅