开始创建提供商托管 SharePoint 加载项

提供商托管加载项是两种主要类型的 SharePoint 加载项之一。若要大致了解 SharePoint 加载项以及这两种不同的加载项类型,请参阅 SharePoint 加载项

下面总结了提供商托管加载项:

  • 它们包含远离 SharePoint 场或 SharePoint Online 订阅托管的 Web 应用、服务或数据库。 它们可能还包含 SharePoint 组件。 外部组件可以托管在任何 Web 托管堆栈上,其中包括 Linux、Apache、MySQL 和 PHP (LAMP) 堆栈。
  • 加载项中的自定义业务逻辑必须运行在外部组件上或自定义 SharePoint 页面上的 JavaScript 中。

在本文中,你将完成以下步骤:

  • 设置开发环境
  • 创建加载项项目
  • 编码加载项

设置开发环境

设置 SharePoint 加载项开发环境的方法有许多种。此部分介绍的是最简单的方法。 对于其他替代环境,例如设置“所有本地”环境,请参阅工具

获取工具

请参考旧版 Visual Studio 或其他 Visual Studio 文档

注册 Office 365 开发人员订阅

注意

可能已有权访问 Office 365 开发人员订阅:

若要获取 Office 365 计划,请执行以下操作:

打开开发人员网站

选择页面左上角的“生成加载项”链接,打开开发人员网站。 应看到如下图所示的网站。 通过页面上的“测试中的加载项”列表,可以确认网站是否是使用 SharePoint 开发人员网站模板制作而成。 相反,如果看到的是常规团队网站,请等待几分钟,再重启网站。

注意

记下网站 URL;在 Visual Studio 中创建 SharePoint 加载项项目时将用到它。

包含“测试中的加载项”列表的开发人员网站主页

显示开发人员网站主页的屏幕截图。

创建加载项项目

  1. 使用“以管理员身份运行”选项启动 Visual Studio。

  2. 在 Visual Studio 中,依次选择“文件”>“新建”>“新建项目”

  3. 在“新建项目”对话框中,依次展开“Visual C#”节点和“Office/SharePoint”节点,再依次选择“加载项”>“SharePoint 加载项”

  4. 将项目命名为“SampleAddIn”,再选择“确定”

  5. 在“指定 SharePoint 加载项设置”对话框中,执行下列操作:

    • 提供要用于调试加载项的 SharePoint 网站的完整 URL。 此为开发人员网站 URL。 请在 URL 中使用 HTTPS,而不是 HTTP。 在此过程的某个时间点,或在完成后不久,将会看到登录此网站的提示。 提示的时间点各异。 使用注册开发人员网站时创建的 *.onmicrosoft.com 域) 中的管理员凭据 (;例如 MyName@contoso.onmicrosoft.com。

    • 在“要如何托管 SharePoint 加载项”下,选择“提供程序托管”

    • 选择“下一步”

  6. 在“指定目标 SharePoint 版本”页上,依次选择“SharePoint Online”和“下一步”

  7. 在“要创建哪种类型的 Web 应用项目?”下,依次选择“ASP.NET Web 表单应用”和“下一步”

  8. 在“要加载项如何进行身份验证?”下,选择“使用 Windows Azure 访问控制服务”

  9. 在向导中,选择“完成”

    许多配置都是在解决方案打开时完成的。 将在 Visual Studio 解决方案中创建两个项目:一个适用于 SharePoint 加载项,另一个适用于 ASP.NET Web 应用。

编码加载项

  1. 打开 AppManifest.xml 文件。 在"权限"选项卡上,指定"网站集"范围和"阅读"权限级别。

  2. 在 Web 应用的 Pages/Default.aspx 文件的 <body> 标记中删除所有标记,再在 <body> 中添加以下 HTML 和 ASP.NET 控件。 此示例使用 UpdatePanel 控件实现部分页面呈现。

     <form id="form1" runat="server">
       <div>
         <asp:ScriptManager ID="ScriptManager1" runat="server"
                 EnablePartialRendering="true" />
         <asp:UpdatePanel ID="PopulateData" runat="server" UpdateMode="Conditional">
           <ContentTemplate>      
             <table border="1" cellpadding="10">
              <tr><th><asp:LinkButton ID="CSOM" runat="server" Text="Populate Data" 
                                    OnClick="CSOM_Click" /></th></tr>
              <tr><td>
    
             <h2>SharePoint Site</h2>
             <asp:Label runat="server" ID="WebTitleLabel"/>
    
             <h2>Current User:</h2>
             <asp:Label runat="server" ID="CurrentUserLabel" />
    
             <h2>Site Users</h2>
             <asp:ListView ID="UserList" runat="server">     
                 <ItemTemplate >
                   <asp:Label ID="UserItem" runat="server" 
                                     Text="<%# Container.DataItem.ToString()  %>">
                   </asp:Label><br />
                </ItemTemplate>
             </asp:ListView>
    
             <h2>Site Lists</h2>
                    <asp:ListView ID="ListList" runat="server">
                        <ItemTemplate >
                          <asp:Label ID="ListItem" runat="server" 
                                     Text="<%# Container.DataItem.ToString()  %>">
                         </asp:Label><br />
                       </ItemTemplate>
                   </asp:ListView>
                 </td>              
               </tr>
              </table>
            </ContentTemplate>
          </asp:UpdatePanel>
       </div>
     </form>
    
  3. 将以下声明添加到 Web 应用的 Default.aspx.cs 文件中。

       using Microsoft.SharePoint.Client;
       using Microsoft.IdentityModel.S2S.Tokens;
       using System.Net;
       using System.IO;
       using System.Xml;
    
  4. 在 Web 应用的 Default.aspx.cs 文件中,将这些变量添加到“Page”类中。

      SharePointContextToken contextToken;
      string accessToken;
      Uri sharepointUrl;
      string siteName;
      string currentUser;
      List<string> listOfUsers = new List<string>();
      List<string> listOfLists = new List<string>();
    
  5. RetrieveWithCSOM 方法添加到“Page”类。 此方法使用 SharePoint CSOM 检索网站相关信息,并在页面上显示检索到的信息。

        // This method retrieves information about the host web by using the CSOM.
      private void RetrieveWithCSOM(string accessToken)
      {
    
          if (IsPostBack)
          {
              sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
          }            
    
          ClientContext clientContext =
                          TokenHelper.GetClientContextWithAccessToken(
                              sharepointUrl.ToString(), accessToken);
    
          // Load the properties for the web object.
          Web web = clientContext.Web;
          clientContext.Load(web);
          clientContext.ExecuteQuery();
    
          // Get the site name.
          siteName = web.Title;
    
          // Get the current user.
          clientContext.Load(web.CurrentUser);
          clientContext.ExecuteQuery();
          currentUser = clientContext.Web.CurrentUser.LoginName;
    
          // Load the lists from the Web object.
          ListCollection lists = web.Lists;
          clientContext.Load<ListCollection>(lists);
          clientContext.ExecuteQuery();
    
          // Load the current users from the Web object.
          UserCollection users = web.SiteUsers;
          clientContext.Load<UserCollection>(users);
          clientContext.ExecuteQuery();
    
          foreach (User siteUser in users)
          {
              listOfUsers.Add(siteUser.LoginName);
          }
    
          foreach (List list in lists)
          {
              listOfLists.Add(list.Title);
          }
      }
    
  6. CSOM_Click 方法添加到“Page”类。 此方法在用户单击“填充数据”链接时触发事件。

      protected void CSOM_Click(object sender, EventArgs e)
    {
        string commandAccessToken = ((LinkButton)sender).CommandArgument;
        RetrieveWithCSOM(commandAccessToken);
        WebTitleLabel.Text = siteName;
        CurrentUserLabel.Text = currentUser;
        UserList.DataSource = listOfUsers;
        UserList.DataBind();
        ListList.DataSource = listOfLists;
        ListList.DataBind();    
     }
    
  7. 将现有的 Page_Load 方法替换为以下方法。 Page_Load 方法使用 TokenHelper.cs 文件中的方法,从 Request 对象中检索上下文,并从 Microsoft Azure 访问控制服务 (ACS) 获取访问令牌。

      // The Page_load method fetches the context token and the access token. 
    // The access token is used by all of the data retrieval methods.
    protected void Page_Load(object sender, EventArgs e)
    {
         string contextTokenString = TokenHelper.GetContextTokenFromRequest(Request);
    
        if (contextTokenString != null)
        {
            contextToken =
                TokenHelper.ReadAndValidateContextToken(contextTokenString, Request.Url.Authority);
    
            sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
            accessToken =
                        TokenHelper.GetAccessToken(contextToken, sharepointUrl.Authority)
                        .AccessToken;
    
             // For simplicity, this sample assigns the access token to the button's CommandArgument property. 
             // In a production add-in, this would not be secure. The access token should be cached on the server-side.
            CSOM.CommandArgument = accessToken;
        }
        else if (!IsPostBack)
        {
            Response.Write("Could not find a context token.");
            return;
        }
    }
    
  8. 完成后,Default.aspx.cs 文件应如下所示。

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;
      using System.Web.UI;
      using System.Web.UI.WebControls;
    
      using Microsoft.SharePoint.Client;
      using Microsoft.IdentityModel.S2S.Tokens;
      using System.Net;
      using System.IO;
      using System.Xml;
    
      namespace SampleAddInWeb
      {
          public partial class Default : System.Web.UI.Page
          {
              SharePointContextToken contextToken;
              string accessToken;
              Uri sharepointUrl;
              string siteName;
              string currentUser;
              List<string> listOfUsers = new List<string>();
              List<string> listOfLists = new List<string>();
    
              protected void Page_PreInit(object sender, EventArgs e)
              {
                  Uri redirectUrl;
                  switch (SharePointContextProvider.CheckRedirectionStatus(Context, out redirectUrl))
                  {
                      case RedirectionStatus.Ok:
                          return;
                      case RedirectionStatus.ShouldRedirect:
                          Response.Redirect(redirectUrl.AbsoluteUri, endResponse: true);
                          break;
                      case RedirectionStatus.CanNotRedirect:
                          Response.Write("An error occurred while processing your request.");
                          Response.End();
                          break;
                  }
              }
    
              protected void CSOM_Click(object sender, EventArgs e)
              {
                  string commandAccessToken = ((LinkButton)sender).CommandArgument;
                  RetrieveWithCSOM(commandAccessToken);
                  WebTitleLabel.Text = siteName;
                  CurrentUserLabel.Text = currentUser;
                  UserList.DataSource = listOfUsers;
                  UserList.DataBind();
                  ListList.DataSource = listOfLists;
                  ListList.DataBind();
              }
    
              // This method retrieves information about the host web by using the CSOM.
              private void RetrieveWithCSOM(string accessToken)
              {
    
                  if (IsPostBack)
                  {
                      sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
                  }
    
                  ClientContext clientContext =
                          TokenHelper.GetClientContextWithAccessToken(
                              sharepointUrl.ToString(), accessToken);
    
                  // Load the properties for the web object.
                  Web web = clientContext.Web;
                  clientContext.Load(web);
                  clientContext.ExecuteQuery();
    
                  // Get the site name.
                  siteName = web.Title;
    
                  // Get the current user.
                  clientContext.Load(web.CurrentUser);
                  clientContext.ExecuteQuery();
                  currentUser = clientContext.Web.CurrentUser.LoginName;
    
                  // Load the lists from the Web object.
                  ListCollection lists = web.Lists;
                  clientContext.Load<ListCollection>(lists);
                  clientContext.ExecuteQuery();
    
                  // Load the current users from the Web object.
                  UserCollection users = web.SiteUsers;
                  clientContext.Load<UserCollection>(users);
                  clientContext.ExecuteQuery();
    
                  foreach (User siteUser in users)
                  {
                      listOfUsers.Add(siteUser.LoginName);
                  }
    
                  foreach (List list in lists)
                  {
                      listOfLists.Add(list.Title);
                  }
              }
    
              protected void Page_Load(object sender, EventArgs e)
              {
                  string contextTokenString = 
                       TokenHelper.GetContextTokenFromRequest(Request);
    
                  if (contextTokenString != null)
                  {
                      contextToken =
                          TokenHelper.ReadAndValidateContextToken(contextTokenString, Request.Url.Authority);
    
                      sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
                      accessToken =
                          TokenHelper.GetAccessToken(contextToken, sharepointUrl.Authority)
                                     .AccessToken;
                      CSOM.CommandArgument = accessToken;
                  }
                  else if (!IsPostBack)
                  {
                      Response.Write("Could not find a context token.");
                      return;
                  }
              }
          }
      }
    
    
  9. 按 F5 键部署并运行加载项。 如果看到“安全警报”窗口,其中询问是否要信任自签名的 Localhost 证书,请选择“是”

  10. 在同意页面上,选择“信任它”,向加载项授权。 Visual Studio 会先将 Web 应用安装到 IIS Express,再将加载项安装到测试 SharePoint 网站并启动它。 将看到内含表的页面,如下面的屏幕截图所示。 若要查看 SharePoint 网站的摘要信息,请选择“填充数据”

基本自托管应用程序启动页

后续步骤

若要创建加载项,请按此顺序执行以下步骤:

  1. 为提供程序托管的加载项提供 SharePoint 外观
  2. 在提供程序托管的外接程序中加入自定义按钮
  3. 快速浏览 SharePoint 对象模型
  4. 将 SharePoint 写入操作添加到提供程序托管的外接程序
  5. 在提供程序托管的外接程序中加入外接程序部件
  6. 处理提供程序托管的外接程序中的外接程序事件
  7. 将首次运行逻辑添加到提供程序托管的外接程序
  8. 以编程方式在提供程序托管的加载项中部署自定义按钮
  9. 在提供程序托管的加载项中处理列表项事件