为提供程序托管的加载项指定 SharePoint 外观

本文是关于开发提供商托管的 SharePoint 加载项的基础知识系列文章中的第 2 篇文章。应先熟悉主题 SharePoint 加载项以及本系列中的概述文章:

本系列的上一篇文章介绍了如何设置开发环境,以及如何使用 Visual Studio 创建首个“Hello World”级别加载项,在加载项远程 Web 应用中呈现 SharePoint 数据。

在本文中,将从已创建的 SharePoint 加载项解决方案入手。 此解决方案包含 ASP.NET Web 表单应用和 SQL Azure 数据库。 这些内容已预先创建完成,因为本系列文章只关注 SharePoint 加载项。本系列的各篇文章将会向加载项添加更多 SharePoint 功能和集成。

了解基本加载项

虽然本系列文章不涉及 ASP.NET 或 T-SQL 编程,但需要先对加载项的远程组件略知一二,然后才能开始将它集成到 SharePoint。 假设加载项的应用场景为一系列连锁零售店,每家连锁店都在总公司的 SharePoint Online 订阅中有一个团队网站。 如果连锁店在自己的团队网站上安装加载项,便可以使用加载项集成自己的 SharePoint 数据,并访问总公司数据库中的数据。 每个加载项实例都在企业数据库中有自己的租赁,用户只能与自家连锁店相关联的企业数据进行交互。

创建两家连锁店的团队网站

  1. 打开 SharePoint Online 网站主页,再选择快速启动上的“网站内容”链接。 在“网站内容”页上,向下滚动到并选择“新子网站”链接。

  2. 在“新 SharePoint 网站”页上,输入下面这些值(另请参阅以下屏幕截图),填写新团队网站表单。

    • 标题:Fabrikam 香港店
    • URL:hongkong

    图 1. 用于创建新的 SharePoint 子网站的表单

    SharePoint 子网站新建表单,其中“标题”文本框中填入的是“Fabrikam 香港店”,“URL”文本框中填入的是“hongkong”。

  3. 保留其他所有设置的默认值,再选择“创建”

了解加载项

  1. 转到 SharePoint_Provider-hosted_Add-Ins_Tutorials,再选择“下载 ZIP”按钮,将存储库下载到桌面。 解压缩文件。

  2. 以管理员身份启动 Visual Studio,再打开 BeforeSharePointUI.sln。 解决方案中有三个项目:

    • ChainStore:SharePoint 加载项项目
    • ChainStoreWeb:远程 Web 应用
    • ChainCorporateDB:SQL Azure 数据库
  3. 选择“ChainStore”项目,并在“属性”窗口中将“网站 URL”属性设置为香港团队网站的完整 URL:https://{YOUR_SHAREPOINT_DOMAIN}/hongkong/(请务必在结尾处添加字符“/”)。 选择“保存”在此过程中,有时会看到登录 SharePoint Online 订阅的提示。

  4. 右键单击“解决方案资源管理器”最上面的解决方案节点,再选择“设置启动项目”

  5. 确保三个项目都在“操作”列中设置为“启动”

  6. 按 F5 键部署并运行加载项。 Visual Studio 在 IIS Express 中托管远程 Web 应用,并在 SQL Express 中托管 SQL 数据库。 此外,它还在测试 SharePoint 网站上临时安装并立即运行加载项。 在加载项的起始页打开前,将会看到向加载项授予权限的提示。

  7. 加载项的起始页如图 2 所示。 最上面是加载项安装到的 SharePoint 网站的名称。 这是由于 Visual Studio 的 Office 开发人员工具生成的一些示例代码间接所致。 将在后续步骤中对此进行更改。 此页面上的其他区域还显示了企业“订单”、“库存”和“员工”SQL 数据库表中的数据。 这些表最初为空。

    图 2. 连锁店加载项的起始页

    连锁店加载项的起始页,其中提供方便查看连锁店库存、订单和员工情况的有标签区域和按钮。

  8. 选择页面底部的“订单表单”链接,打开订单表单。 在表单中输入一些值,再选择“下订单”。 例如,图 3 中的屏幕截图。 看起来好像什么都没有发生,但代码隐藏按钮却将值传递到了 SQL 数据库中的参数化存储过程。 使用参数化存储过程可让数据库免遭 SQL 注入攻击。

    图 3. 订单窗体

    订单表单,其中包含“供应商”、“产品”和“数量”文本框,以及标记为“下订单”的按钮。

  9. 使用浏览器的“后退”按钮返回到起始页,再选择“显示订单”按钮。 此时,起始页便会进行刷新,并显示订单,如图 4 中的屏幕截图所示。

    图 4. 选择“显示订单”后的起始页

    起始页上显示订单的部分,其中一个订单显示在 HTML 表中。它具有 ID、租户、供应商、产品和数量列。

    表中的“租户”字段值为测试 SharePoint 网站的 URL。 这并不是指 SharePoint Online 订阅(有时亦称为“租赁”)。 相反,每个加载项实例都是企业数据库中的唯一租户。 由于只能在特定 SharePoint 主机 Web 上安装一个加载项实例,因此主机 Web URL 可用作数据库中的租户鉴别器。 (若要回顾主机 Web 和加载项 Web 的区别,请参阅 SharePoint 加载项。)

    对数据库执行写入或读取操作时,加载项中的所有存储过程都添加鉴别器值。 这样可确保在用户选择“显示订单”(或“显示库存”或“显示员工”)时,只从数据库中检索与用户连锁店相关联的数据。 这种设计还可确保用户只能为自己的连锁店下订单和添加员工。

    远程 Web 应用从查询字符串参数中获取主机 Web URL,这是 SharePoint 在启动加载项时添加到起始页 URL 中的参数。 因为使用的是 SSL,所以此查询字符串在从跨 Internet 传输到远程 Web 应用的过程中是加密的。

  10. 若要结束调试会话,请关闭浏览器窗口或停止在 Visual Studio 中进行调试。 每次按 F5,Visual Studio 都会撤回旧版加载项并安装最新版本。

  11. 默认情况下,在 Visual Studio 中的调试会话期间,加载项仍安装在 SharePoint 主机 Web 上。 若要了解最终用户在安装加载项后如何启动它,请在浏览器中打开 Fabrikam 香港 SharePoint 网站,并转到“网站内容”页。 将看到加载项磁贴,如下面的屏幕截图所示。

图 5. Chain Store 加载项的启动磁贴

“网站内容”页上的连锁店加载项启动磁贴,其中显示加载项的图标和名称。

注意

如果在选择磁贴后起始页没有打开,这是因为 Visual Studio 在调试停止时关闭了 IIS Express 会话。

将 Visual Studio 配置为通过每个调试会话重建企业数据库

默认情况下,Visual Studio 不会 重新生成 SQL Express 数据库。 因此,在一个调试会话中添加到数据库的订单和其他项在后续会话中仍位于此数据库中。 不过,每次按 F5 时,从空数据库入手会更加简单。因此,请按照以下步骤操作:

  1. 右键单击“ChainCorporateDB”项目,再选择“属性”

  2. 打开“调试”选项卡,并启用“始终重新创建数据库”选项。

为远程 Web 应用程序提供 SharePoint 外观

在某些情况下,您希望远程页面具有自己的品牌,但在大多数情况下,它们的 UI 应该与 SharePoint 相仿,使用户感觉仍在使用 SharePoint。

将 SharePoint 部件版式和顶栏添加到起始页

  1. 在“解决方案资源管理器”中,依次转到“ChainStoreWeb”>“页面”,再打开 CorporateDataViewer.aspx 文件(即加载项的起始页)。

  2. “头”部分中包含用于加载一些 JavaScript 库的脚本。 在它下面额外添加以下脚本。 此脚本加载 SP.UI.Controls.js 文件,该文件位于 /_layouts/15/ 文件夹中的每个 SharePoint 网站中。 除此之外,此文件还加载 SharePoint CSS 库。

      <script type="text/javascript">
        var hostweburl;
    
        // Load the SharePoint resources.
        $(document).ready(function () {
    
            // Get the URI decoded add-in web URL.
            hostweburl =
                decodeURIComponent(
                    getQueryStringParameter("SPHostUrl")
            );
    
            // The SharePoint js files URL are in the form:
            // web_url/_layouts/15/resource.js
            var scriptbase = hostweburl + "/_layouts/15/";
    
            // Load the js file and continue to the 
            // success handler.
            $.getScript(scriptbase + "SP.UI.Controls.js")
        });
    
        // Function to retrieve a query string value.
        function getQueryStringParameter(paramToRetrieve) {
            var params =
                document.URL.split("?")[1].split("&amp;");
            var strParams = "";
            for (var i = 0; i < params.length; i = i + 1) {
                var singleParam = params[i].split("=");
                if (singleParam[0] == paramToRetrieve)
                    return singleParam[1];
            }
        }
    </script>
    
  3. 在页面正文部分的最上面,添加以下标记。 这会将称为“部件版式控制”的 SharePoint 顶栏插入页面。 本文稍后将介绍如何测试修改后的加载项,届时将会更清楚地了解此标记的详细信息(字符串“app”出现在一些属性名中,因为加载项过去常常称为“应用”)。

      <!-- Chrome control placeholder. Options are declared inline.  -->
    <div 
        id="chrome_ctrl_container"
        data-ms-control="SP.UI.Controls.Navigation"  
        data-ms-options=
            '{  
                "appHelpPageUrl" : "Help.aspx",
                "appIconUrl" : "/Images/AppIcon.png",
                "appTitle" : "Chain Store",
                "settingsLinks" : [
                    {
                        "linkUrl" : "Account.aspx",
                        "displayName" : "Account settings"
                    },
                    {
                        "linkUrl" : "Contact.aspx",
                        "displayName" : "Contact us"
                    }
                ]
             }'>
    </div>
    
  4. H1 头和页面正文中的超链接自动使用 SharePoint CSS 库中定义的样式,因此无需更改它们。 为了说明如何使用 SharePoint 样式,请将 HeaderStyle CssClass 属性添加到三个 GridView 控件中,并将值设置为“ms-uppercase”,从而将三个控件中的列标题设置为 SharePoint 的“全部大写”样式。 示例如下。 对全部三个 GridView 控件执行相同的更改。

      <asp:GridView ID="ordersGridView" runat="server" CellPadding="5" GridLines="None" 
    HeaderStyle-CssClass="ms-uppercase" />
    
  5. 由于部件版式控制使用加载项图标,因此远程 Web 服务器上需要有图标文件的另一个副本。 在“解决方案资源管理器”中,右键单击“ChainStore”项目中的 AppIcon.png 文件,再选择“复制”

  6. 右键单击“ChainStoreWeb”项目中的“图像”文件夹,再选择“粘贴”

  7. 打开 CorporateDataViewer.aspx.cs 文件。

  8. CorporateDataViewer 类声明类型为 SharePointContext 的私有成员。 此类在 SharePointContext.cs 文件中进行定义,这个文件是由 Visual Studio 的 Office 开发人员工具在项目创建时生成。 可以将它看作是 ASP.NET 的 HttpContextBase 类,不同之处在于还包含 SharePoint 上下文信息(如主机 Web URL)。

    Page_Load 方法中,using 语句将 SharePoint 主机 Web 名称写入远程起始页。 由于这是示例代码,因此请删除整个 using 语句(但保留初始化 spContext 变量的代码行)。 此时,方法应如下所示。

      protected void Page_Load(object sender, EventArgs e)
    {
        spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
    }
    
  9. 还有以下四个 ASP.NET 文件需要使用 SharePoint UI:

    • Account.aspx
    • Contact.aspx
    • Help.aspx
    • OrderForm.aspx

    注意

    项目中的最后一个 aspx 文件 EmployeeAdder.aspx 从未实际呈现过,因此您未更改其 UI。 本系列的下一篇文章中将对其进行详细介绍。

    不用在这些页面上添加部件版式控制。 只需能够访问 SharePoint CSS 库即可。 对于所有这四个文件,将以下标记添加到 head 元素中。

      <link type="text/css" rel="stylesheet" 
    href="<%= spContext.SPHostUrl.ToString() + "_layouts/15/defaultcss.ashx" %>" />
    
  10. 由于已对“订单表单”页和“帐户”页完成这一步和下一步,因此这两步仅应用于“联系人”页和“帮助”页。 若要在每个页面上获取 spContext 对象,请打开三个 aspx 页面的 *.aspx.cs 代码隐藏文件。 在每个页面中,将以下成员添加到 Page 类。

      protected SharePointContext spContext;
    
  11. Page_Load 方法替换为以下版本。 将从会话缓存中检索对象。 外接程序的起始页的 Page_Load 方法第一次创建对象时将其缓存在那里。

      protected void Page_Load(object sender, EventArgs e)
    {
        spContext = Session["SPContext"] as SharePointContext;
    }
    
  12. 打开 OrderForm.aspx 页面。 在最上面的“Label”元素中,将短语“Place Order”上的 <b> 元素替换为引用 ms-accentText CSS 类的 span 标记。 完成时,整个 Label 控件应如下所示。

      <asp:Label ID="lblOrderPrompt" runat="server"
             Text="Enter a supplier, product, and quantity; and then press <span class='ms-accentText'>Place Order</span>.">
    </asp:Label>
    

运行加载项并测试新 SharePoint UI

  1. 按 F5 键部署并运行加载项。 Visual Studio 在 IIS Express 中托管远程 Web 应用,并在 SQL Express 中托管 SQL 数据库。 此外,它还在测试 SharePoint 网站上临时安装并立即运行加载项。 在加载项的起始页打开前,将会看到向加载项授予权限的提示。

  2. 打开后的加载项起始页的外观现在与 SharePoint 页面一样。 选择“订单表单”链接。 现在,它的外观也与 SharePoint 表单一样。

    图 6. 具有 Segoe 字体和突出显示的“下订单”的“订单窗体”

    还是“订单表单”。现在它使用 Segoe 字体,并将“下订单”短语突出显示为蓝色。

  3. 创建订单,再选择“下订单”

  4. 使用浏览器的“后退”按钮返回到加载项起始页,再选择“显示订单”。 此时,页面应如下所示。 请注意,列标题现在全部大写。

    图 7. 具有部件版式控件的起始页

    最上面采用部件版式控制的起始页。所有文本和控件均使用 SharePoint 样式。

  5. 选择部件版式控件末尾的 “? ”图标。 此时,简单帮助页面打开。 选择浏览器的“后退”按钮。

  6. 选择部件版式控制上的齿轮图标。 此时,内含“帐户”页和“联系人”页链接的菜单打开。 打开“帐户”页,并使用浏览器的“后退”按钮返回到起始页。 对“联系人”页执行相同的操作。

  7. 选择部件版式控制上的“返回到网站”按钮。 此时,主机 Web 主页(即香港店团队网站)打开。

  8. 依次选择顶栏上的齿轮图标和“更改外观”

  9. 按照提示操作,将网站更改为采用一种备用“外观”。

  10. 导航到“网站内容”页面并从其图块启动连锁店应用。 您的自定义页面已应用所选的外观。 以下屏幕截图显示了页面在“自然”组合外观下是什么样的。

图 8. 具有“自然”组合外观的起始页和订单窗体

采用“自然组合”外观的浅绿色设置的加载项起始页和订单表单。

  1. 将网站的外观更改回默认设置,即“Office”

  2. 若要结束调试会话,请关闭浏览器窗口或停止在 Visual Studio 中进行调试。 每次按 F5,Visual Studio 都会撤回旧版加载项并安装最新版本。

  3. 将在其他文章中使用此加载项和 Visual Studio 解决方案,因此最好在使用一段时间后,再最后撤回一次加载项。 在“解决方案资源管理器”中,右键单击此项目,再选择“撤回”

后续步骤

外接程序现在看起来类似于 SharePoint,但除了它从 SharePoint 中的图块启动之外,它仍然是 Web 应用程序,并未真正与 SharePoint 集成。 在下一篇文章中,您将添加从自定义功能区按钮启动的自定义命令: 在提供程序托管的外接程序中包含自定义按钮