CSOMでSharePointのナビゲーションを読み取る

SharePoint Onlineに対して、プログラムからサイドリンクバーやトップリンクバーにアクセスする方法を説明します。

確認環境:Visual Studio 2017(C#), Office 365 Business Premium, CSOM

SharePoint Onlineへの接続

前提条件としてCSOMのClientContextクラスのオブジェクトは作成済みで、SharePoint Onlineの認証も済んでいるとします。

この方法は以前に書きました。

C#でSPOに接続する方法

CSOMでは、ClientContextを用いて、SharePoint Onlineのサイトからサイドリンクバーやトップリンクバーの情報を取得することになります。

サイドリンクバー

サイドリンクバーは各サイト別に作成する画面左側のリンク集です。

サイドリンクバーにアクセスするためには、Microsoft.SharePoint.Client.WebクラスのNavigationプロパティ(Microsoft.SharePoint.Client.Navigationクラス)にアクセスし、更にそのQuickLaunchプロパティと順を追う必要があります。

MSDN:.QuickLaunch

このプロパティはMicrosoft.SharePoint.Client.NavigationNodeCollectionクラスです。つまりforeachで回せます。

個別のNavigationNodeはTitleプロパティでリンクテキスト、UrlはリンクのURL。

また、リンクを親子の2階層で持つことができ、その際はNavaigationNodeクラスが持つChildrenプロパティからそのリンクの子のリンクにアクセスです。TitleやUrlと違ってcontext.Loadする際に、Childrenプロパティを明示的にIncludeしないといけません。

以下のように取得します。コンソールプログラムのプロジェクトです。プロパティ出力ロジックは、トップリンクバーと共有することを考えてメソッドに切り出しました。

var navigation = web.Navigation;
context.Load(navigation.QuickLaunch, includes => 
        includes.Include(i => i.Title, i => i.Url, 
                         i => i.Children));
context.ExecuteQuery();
// サイドリンクバー
Console.WriteLine("サイドリンクバー:");
navigation.QuickLaunch
          .ToList()
          .ForEach(navigationNode =>
                   PrintNavigation(navigationNode));
                               
                               
static void PrintNavigation(NavigationNode node, bool isParentLevel = true)
{
    var spaces = isParentLevel ? "\t" : "\t\t";
    var message = string.Format("{0}リンクテキスト:{1} URL:{2}", 
                                spaces, node.Title, node.Url);
    Console.WriteLine(message);

    // 子リンクがあればタブで頭下げして出力する
    //(MSDNによるとChildrenプロパティはnullにはならないのでチェックしない)
    if (isParentLevel)
        node.Children.ToList().ForEach(childNode => 
                                       PrintNavigation(childNode, false));
}

結果例

サイドリンクバー:
        リンクテキスト:ホーム URL:/
        リンクテキスト:ドキュメント URL:/Shared Documents/Forms/AllItems.aspx
        リンクテキスト:最近使った項目 URL:
                リンクテキスト:task URL:/Lists/task/AllItems.aspx
                リンクテキスト:リンク集 URL:/Lists/List3/AllItems.aspx
        リンクテキスト:サイトのページ URL:/SitePages/Forms/AllPages.aspx
        リンクテキスト:サブサイト URL:/_layouts/15/viewlsts.aspx?ShowSites=1
        リンクテキスト:ページ URL:/SitePages/Forms/AllPages.aspx
        リンクテキスト:サイト コンテンツ URL:/_layouts/15/viewlsts.aspx

トップリンクバー

トップリンクバーはサイト上部のリンク集です。

基本的にはサイドリンクバーと同じです。QuickLaunchプロパティの代わりにTopNavigationBarプロパティにアクセスします。

このプロパティもNavigationNodeCollectionなのは同じ。

よってサンプルコードも似ています。

var navigation = web.Navigation;
context.Load(navigation.TopNavigationBar, includes => 
        includes.Include(i => i.Title, i => i.Url, 
                         i => i.Children));
context.ExecuteQuery();
// トップリンクバー
Console.WriteLine("トップリンクバー:");
navigation.TopNavigationBar
          .ToList()
          .ForEach(navigationNode =>
                   PrintNavigation(navigationNode));     

結果例

トップリンクバー:
        リンクテキスト:ホーム URL:/
        リンクテキスト:ハウスソフト URL:/house-soft
        リンクテキスト:実験用 URL:/experiments
        リンクテキスト:株 URL:/stock

ただし、リンクの継承をしているサブサイトを対象にこのサンプルコードを動かすと結果は空です。

その場合は、継承元のサイトを対象にする必要があるようです。