SharePoint Foundation 2010 中的流体应用程序模型概述

**摘要:**介绍如何在 Web 部件中承载 Microsoft SharePoint 外部应用程序(如 Microsoft Silverlight 应用程序)并了解流体应用程序模型。

上次修改时间: 2011年1月12日

Microsoft 图标 Ricky Kirkham,Microsoft Corporation

本文内容
外部应用程序集成概述
不同的开发级别
流体应用程序模型的关键要素
外部应用程序提供程序
创建宿主 Web 部件
开发任务
结束语
其他资源

2009 年 11 月

适用范围: Business Connectivity Services | Office 2010 | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio

目录

  • 外部应用程序集成概述

  • 不同的开发级别

  • 流体应用程序模型的关键要素

  • 外部应用程序提供程序

  • 创建宿主 Web 部件

  • 开发任务

  • 结束语

  • 其他资源

外部应用程序集成概述

在某些情况下,拥有参与者权限的网站用户可以将承载 Microsoft SharePoint 外部应用程序(如 Microsoft Silverlight 应用程序)的 Web 部件添加到他们的页面中。对 Microsoft SharePoint Foundation 2010 用户而言,如果能够承载与 SharePoint Foundation Web 应用程序位于不同的域中的应用程序,无疑是一项巨大进步,因为许多此类应用程序都可以承载在应用程序服务器上并提供给场中的所有 Web 应用程序使用。SharePoint Foundation 2010 引入了流体应用程序模型 (FAM) 以通过一种安全的方式实现此方案。

FAM 使管理员可以控制外部应用程序的权限,而不会过度限制用户将承载这些应用程序的 Web 部件添加到 Web 部件页的能力。当某应用程序符合 FAM 时,装有该应用程序的服务器会以特殊类型用户(称为应用程序主体)的身份登录到 SharePoint Foundation Web 应用程序。应用程序的权限是管理员授予此特殊用户的权限与打开网页(该网页包含承载应用程序的 Web 部件)的实际用户的权限的交集。这些 Web 部件可为开发小组提供将非 SharePoint 应用程序集成到 SharePoint Foundation 网站的快速方式。

通常,如果外部服务器承载用于 SharePoint Foundation 的多个应用程序,那么所有此类应用程序将使用相同的应用程序主体用户凭据。您可以为每个应用程序创建不同的应用程序主体用户,但没有什么可以阻止该服务器将其任何应用程序主体用户用于其任意应用程序。

备注

Silverlight 中的 HTTP 通信和安全:跨域通信 中描述的任何四种方式中,如果应用程序的可执行文件的 URI 与 Web 应用程序的 URI 不同,则该应用程序是外部 SharePoint Foundation Web 应用程序(即,它位于其他域中)。

不同的开发级别

将某应用程序集成到 SharePoint Foundation 中的开发工作量的大小主要取决于以下因素。

  • 该应用程序的可执行文件是承载在 SharePoint Foundation Web 应用程序中还是承载在某个外部域中。

  • 该应用程序是否需要读写 SharePoint Foundation 数据。

  • 是否需要更改控制 Web 部件呈现方式的默认设置。

  • 该应用程序是否需要自定义配置信息,以便能够在 SharePoint Foundation Web 部件中运行。

  • 在创建和编辑承载该应用程序的 Web 部件的属性时,是否需要使用 SharePoint Foundation 中的自定义 UI。

在最为简单的情况下,非 SharePoint 应用程序或者 位于 SharePoint Foundation Web 应用程序所在的域中,或者 承载在外部 URL 中,但它不需要访问 SharePoint 数据。在上述任一情况下,都不需要进行 SharePoint 开发。当完成可执行文件后,Web 应用程序管理员会将其部署到应用程序服务器或文档库中。当添加可以承载非 SharePoint 应用程序的 Web 部件的用户添加该 Web 部件时,系统将提示这些用户提供该可执行文件的 URL。如果应用程序部署在本地,则它可以使用当前用户上下文中的托管客户端对象模型访问 SharePoint Foundation 数据。(如果外部应用程序是 Silverlight 应用程序,它可以使用特殊的 Silverlight 客户端对象模型。)

如果要将应用程序部署到与 Web 应用程序不同的域中,并且 该应用程序将需要访问 SharePoint 数据,则集成需要使用 FAM。

流体应用程序模型的关键要素

下面是 FAM 中开发人员需注意的一些关键要素。

  • 场管理员必须通过注册外部应用程序提供程序 (EAP) 来支持从外部域中的应用程序访问 SharePoint Foundation 数据。出于安全原因,无法在 SharePoint Foundation UI 中实现此目的,而是必须以编程方式实现。您可以在解决方案中包含所需代码的相关说明,或者为服务器场管理员提供一个要运行的小型实用程序。有关创建此实用程序代码的详细信息,请参阅下文中的启用外部应用程序提供程序。

    备注

    只需注册一次 EAP,即使要使用多个外部应用程序时也是如此。

  • 必须创建某个外部应用程序 XML 标记,以便为 SharePoint Foundation 提供所需的应用程序相关信息。系统会提示添加可承载应用程序的 Web 部件的用户提供此标记,因此必须为这些用户提供此标记。有关创建此标记的详细信息,请参阅下文中的创建外部应用程序 XML。

  • 场管理员必须创建外部应用程序用于登录到 SharePoint Foundation 的用户标识,并且必须将该用户配置为应用程序主体。出于安全原因,不能在 UI 中进行此项配置。您必须提供一个实用程序,以便为 SPUser 对象(该对象代表需要跨域访问 SharePoint Foundation 数据的应用程序)的特定属性赋值。有关创建此实用程序的详细信息,请参阅下文中的创建应用程序主体。希望其参与者能够添加承载应用程序的 Web 部件的网站所有者必须将应用程序主体作为用户添加到他们的网站中。

  • 您必须创建一个安装在外部应用程序所在域中的 HTTP 请求处理程序。来自外部应用程序的、对 SharePoint Foundation Web 应用程序的请求将首先被定向到该处理程序,然后该处理程序会将这些请求与安全哈希和用户凭据一同转发到 SharePoint Foundation 前端 Web 服务器。有关创建该处理程序的详细信息,请参阅下文中的创建 HTTP 请求转发器。

  • Silverlight 应用程序中用于向 SharePoint Foundation Web 应用程序读取/写入数据的代码使用 SharePoint Foundation 客户端对象模型的特殊 Silverlight 版本,该模型是在其自己的客户端程序集中实现的。有关此对象模型及对其进行编程的详细信息,请参阅使用 Silverlight 对象模型

备注

尽管 在应用程序位于外部域中 它需要访问 SharePoint Foundation 数据时才执行上述任务,但您可能仍希望在不满足其中某个条件时完成这些任务。例如,您可能希望使用外部应用程序 XML 自定义 Web 部件的宽度和高度。

外部应用程序提供程序

EAP 是一种用于承载非 SharePoint 应用程序的 Web 部件的配置和设置引擎。它可以解释外部应用程序 XML,管理承载应用程序的 Web 部件的创建过程,以及管理 Web 部件的属性的编辑过程。

除非注册自定义 EAP,否则将使用默认 EAP。服务器场中的每个 SPWebService 对象只能有一个 EAP。因此所有 Web 应用程序(它们是同一 Web 服务的子级)中 Web 部件承载的所有外部应用程序均由同一 EAP 进行管理。有关 SPWebService 和 Web 服务的详细信息,请参阅 Microsoft SharePoint Foundation 的服务层次结构背景:Microsoft SharePoint Foundation 中的服务实体

您可以创建自定义 EAP 并用它替换默认 EAP。您可能希望在以下情况下执行此操作:

  • 承载非 SharePoint 应用程序的 Web 部件需要一个用户可部署的自定义工具部件,以编辑该 Web 部件的属性或完成其他工作。例如,此类工具部件可以打开一个包含按钮的自定义应用程序注册页,该自定义页的代码隐藏功能可为外部应用程序创建应用程序主体用户。

  • Web 部件需要自定义的部件版式。

  • 外部应用程序(更确切地说是应用程序的请求转发器)需要客户端哈希,以便可以确认从 SharePoint Foundation 前端 Web 服务器收到的查询响应尚未更改。有关请求转发器的详细信息,请参阅下文中的创建 HTTP 请求转发器。

  • Web 部件的外部应用程序 XML 需要包含自定义配置属性。

  • 创建 Web 部件的子控件时需要执行自定义逻辑。

有关创建自定义 EAP 的详细信息,请参阅下文中的创建自定义外部应用程序提供程序。

创建宿主 Web 部件

用于承载 Silverlight 应用程序的 Web 部件包括在 SharePoint Foundation 中。如果希望在 Web 部件中承载其他种类的应用程序,则可以从 ClientApplicationWebPartBase 派生新的 Web 部件类型。有关创建承载非 SharePoint 应用程序的 Web 部件的详细信息,请参阅下文中的创建宿主 Web 部件。

开发任务

创建外部应用程序 XML

外部应用程序 XML 是一个标记,可为 SharePoint Foundation 提供有关 Web 部件中承载的 Silverlight 应用程序的信息。仅当 Silverlight 应用程序承载在其他域中且访问 SharePoint 网站数据时,才需要此标记。还可在使用 EAP 时使用此标记(尽管并不需要它)。此标记提供三个类别的信息:

  • 有关 Silverlight 应用程序及其用于从 SharePoint 网站获取数据的应用程序主体名称的标识信息。

  • 有关承载外部应用程序的 Web 部件的信息。

  • 自定义 EAP 可用于注册外部应用程序的自定义信息。

可采用以下多种方式向 Web 部件分配标记:

  • 在向页面中添加 Web 部件时,可以在 SharePoint Foundation UI 中向该 Web 部件分配标记。如果您的 Silverlight Web 部件解决方案使用此方法,则需要使用此 UI 以文件形式为用户提供此标记,该文件中需附加有关如何插入标记的说明,可能还需要附加本地修改内容。

  • 还可以在功能定义 (elements.xml) 或网站定义 (onet.xml) 中,将标记指定为模块的 Web 部件标记中的 ApplicationXML 属性。

  • 最后,您可以在 FeatureInstalledFeatureActivated 等事件中以编程方式设置 ApplicationXml 属性。

外部应用程序 XML 示例

下面是一个外部应用程序 XML 标记示例。有关相关元素和属性的详细信息,请参阅外部应用程序 XML。UTF-16 在此示例中用作编码,您也可以使用任意编码。customProperties 元素的子元素可以是任何 XML 标记。如果使用自定义属性,则必须创建自定义 EAP 以读取和处理这些自定义属性。(请参阅创建自定义外部应用程序提供程序。)

<?xml version='1.0' encoding='utf-16'?>
<applicationParts xmlns='https://schemas.microsoft.com/sharepoint/2009/fluidapp'>
  <applicationPart>
    <metaData>
      <applicationId>00000000-0000-0000-0000-000000000000</applicationId>
      <applicationUrl>https://www.contoso.com/someapplication.xap</applicationUrl>
      <principal>domain\username</principal>
      <sharepointRequestHandlerUrl>/sp.ashx</sharepointRequestHandlerUrl>
    </metaData>
    <data>
      <webPartProperties>
        <property name='Title'>Title</property>
        <property name='Description'>Description</property>
        <property name='WindowlessMode'>TRUE</property>
        <property name='Height'>200px</property>
        <property name='Width'>100px</property>
        <property name='HelpUrl'>https://www.contoso.com/someapplication/help.aspx</property>
        <property name='HelpMode'>Modal</property>
        <property name='Direction'>NotSet</property>
        <property name='MinRuntimeVersion'>3.0</property>
      </webPartProperties>
      <customProperties>
        <property name='CustomPropertyName'>CustomPropertyInfo </property>
      </customProperties>
    </data>
  </applicationPart>
</applicationParts>

下面是一个外部应用程序 XML 示例,该外部应用程序 XML 位于 elements.xml 或 onet.xml 文件中的 AllUsersWebPart 元素内。

<AllUsersWebPart WebPartZoneID="Top_Right" WebPartOrder="2">
<![CDATA[
<webParts>
  <webPart xmlns="https://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name="Microsoft.SharePoint.WebPartPages.SilverlightWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=94de0004b6e3fcc5" />
      <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="ChromeType" type="chrometype">Default</property>
        <property name="Height" type="unit">600px</property>
        <property name="Url" type="string" />
        <property name="HelpMode" type="helpmode">Navigate</property>
        <property name="ApplicationXml" type="string">&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;applicationParts xmlns="https://schemas.microsoft.com/sharepoint/2009/fluidapp"&gt;
  &lt;applicationPart&gt;
    &lt;metaData&gt;
      &lt;applicationId&gt;00000000-0000-0000-0000-000000000000&lt;/applicationId&gt;
      &lt;applicationUrl&gt;https://server/ClientBin/SomeApplication.xap&lt;/applicationUrl&gt;
      &lt;principal&gt;domain\ContosoApp&lt;/principal&gt;
      &lt;sharepointRequestHandlerUrl&gt;/ReqForwarder.ashx&lt;/sharepointRequestHandlerUrl&gt;
    &lt;/metaData&gt;
  &lt;/applicationPart&gt;
&lt;/applicationParts&gt;</property>
        <property name="Hidden" type="bool">False</property>
        <property name="Title" type="string" />
      </properties>
    </data>
  </webPart>
</webParts>
]]>
</AllUsersWebPart>

启用外部应用程序提供程序

场管理员必须将 ExternalApplicationSettings.Enabled 属性设置为 true 才能通过 EAP(包括默认 EAP)管理外部应用程序。设置该属性后,在 ExternalApplicationSettings.Provider 属性中指定的 EAP 将成为 Web 服务内所有 Web 应用程序中所有外部应用程序的管理程序。除非该提供程序已设置为其他项,否则将使用 SharePoint Foundation 中包括的默认提供程序。

无法在 UI 中设置此属性,因此场管理员必须以编程方式进行设置。下面显示的是 C# 代码。(请注意,必须调用 Update() 才能保留对配置数据库的更改。)

SPWebService.ContentService.ExternalApplicationSettings.Enabled = true;
SPWebService.ContentService.Update(); 

场管理员可以使用 Windows PowerShellAdd-Type cmdlet 运行此代码,您也可以为场管理员提供实用程序。理论上讲,此代码可以位于控制台应用程序、自定义 PowerShell cmdlet、应用程序页上某控件的 Click 事件处理程序中,或者任何其他形式的可执行代码中。但是,对于管理员来说,使用 Add-Type 可能最为简便。下面的过程演示一种通过创建 PowerShell 脚本来执行此操作的方式。

创建和运行使用 Add-Type 启用 EAP 的 PowerShell 脚本

  1. 将以下内容添加到某个文本文件中。

    Add-type @"
    using System;
    using Microsoft.SharePoint.Administration;
    
    namespace ContosoCmdlets
    
        public class EAPEnabler
        {
            public static void EnableEAP()
            {
                SPWebService.ContentService.ExternalApplicationSettings.Enabled = true;
                SPWebService.ContentService.Update(); 
            }
        }
    "@ -Language CsharpVersion3
    [ContosoCmdlets.EAPEnabler]::EnableEAP()
    
  2. 将该文件另存为 EAPEnable.ps。

  3. 在 PowerShell 窗口中运行该脚本。

创建应用程序主体

出于安全原因,管理员无法在 SharePoint Foundation UI 中添加应用程序主体,而只能使用代码创建应用程序主体。通常,代码位于小型控制台应用程序中,但它也可能位于自定义 PowerShell cmdlet,使用 Add-Type cmdlet 的 PowerShell 脚本或者其他任何可执行上下文中。

必须在要向其中添加应用程序主体用户的网站的父网站集管理员上下文中运行此代码。

创建应用程序主体

  1. 将对 Microsoft.SharePoint.dll 的引用添加到您的 C# 项目以及 Microsoft.SharePoint 的 using 语句中。

  2. 获取对要向其中添加应用程序主体用户的网站的引用。下面是一个示例。

    SPSite site = new SPSite("https://localhost");
    SPWeb web = site.RootWeb;
    
  3. 通过调用 AddApplicationPrincipal(String, Boolean, Boolean) 创建用户对象。在此示例中,为该用户指定了一个包含提醒的名称,代表装有一个或多个外部应用程序的外部服务器。两个 Boolean 参数将用户的 AllowBrowseUserInfoRequireRequestToken 属性分别设置为其各自的建议值。这样可以确保:

    • 应用程序不能访问用户信息,即使为其分配的权限在其他情况下允许其具有此类访问权限。

    • 应用程序根本不能访问 SharePoint Foundation Web 应用程序,除非该应用程序承载在实际用户已导航到的页面上的 Web 部件中。该应用程序的有效权限是为其分配的权限和实际用户权限的交集。

    SPUser principal = web.AddApplicationPrincipal("ContosoAppServer", false, true);
    
    重要说明重要说明

    传递到 AddApplicationPrincipal(String, Boolean, Boolean) 的名称(在此示例中为"ContosoAppServer")必须是验证系统已知用户(例如,Active Directory 中已存在的用户)的名称,但该用户还不是网站用户。

  4. 为应用程序主体分配权限级别。在此示例中,将应用程序主体指定为参与者。

    SPRoleDefinitionBindingCollection roleDefBindCol = new SPRoleDefinitionBindingCollection();
    roleDefBindCol.Add(web.RoleDefinitions.GetByType(SPRoleType.Contributor));
    
    SPRoleAssignment roleAssign = new SPRoleAssignment(principal);
    roleAssign.ImportRoleDefinitionBindings(roleDefBindCol);
    
    web.RoleAssignments.Add(roleAssign);
    

创建 HTTP 请求转发器

某些应用程序(如 Silverlight)无法进行跨域请求。当应用程序需要与另一个域中的服务器通信时,系统必须首先将其请求发送到请求转发处理程序(当然,该处理程序与应用程序位于同一域中)。该处理程序然后会重新打包此请求并将其发送到外部域中的目标服务器。

在这种情况下,必须创建请求转发器。例如,如果 Silverlight Web 部件承载的 Silverlight 应用程序所在的域与其页面包含 Web 部件的 SharePoint Foundation Web 应用程序所在的域不同,并且该应用程序需要向 Web 应用程序发送请求,则必须在 Silverlight 应用程序所在的域中创建并安装请求转发处理程序。在向页面中添加 Web 部件后,会在外部应用程序 XML 中指定该处理程序的 URL。有关创建此 XML 的详细信息,请参阅下文中的创建外部应用程序 XML。

该处理程序所需的大部分逻辑位于 RequestForwarder 类中。您所创建的处理程序类是对此类进行的一种包装。

创建请求转发处理程序

  1. 在您的 Visual Studio 项目中添加一个纯文本文件,并为其指定 ashx 扩展名。

  2. 在页的顶端添加一个 WebHandler 指令。使用 Language 和 Class 属性指定实现该处理程序的编程语言和类。下面是一个示例。

    <%@ WebHandler Language="C#" Class="ToSharePointForwarder" %>
    
  3. 在该指令的下方正确添加代码,就像在普通代码文件中添加代码一样。首先添加 using 语句,并为 Microsoft.SharePoint.Client 命名空间添加该语句。

    using System;
    using System.Web;
    using Microsoft.SharePoint.Client;
    
  4. 为处理程序类添加声明。因为它是一个 HTTP 处理程序,所以它必须实现 IHttpHandler 接口。

    public class ToSharePointForwarder : IHttpHandler 
    {    
    }
    
  5. 添加 IsReusable 属性的实现。它应仅返回 false。

    public bool IsReusable 
    {
        get { return false; }
    }
    
  6. 添加 ProcessRequest(HttpContext) 方法的实现。在很大程度上,实现只是对 RequestForwarder 类的 ProcessRequest() 方法进行的包装。但是,您必须首先将应用程序主体凭据添加到请求中。在此示例中,通过应用程序主体用户的名称和密码以及该用户的 Active Directory 域来构造 NetworkCredential

    public void ProcessRequest (HttpContext context) 
    {
        RequestForwarder forwarder = new RequestForwarder(context);
        if (!String.IsNullOrEmpty(forwarder.Url))
        {
            forwarder.WebRequest.Credentials 
                = new System.Net.NetworkCredential("ContosoSilverlightApp", "&Tu*)2v", "Contoso");
            forwarder.ProcessRequest();
        }
    }
    

创建自定义外部应用程序提供程序

创建自定义 EAP 需要从一个或两个抽象类派生新类:

重要说明重要说明

在考虑是否创建自定义 EAP 时,请记住,所有 SharePoint Foundation Web 应用程序(它们是给定 Web 服务的子级)中承载应用程序的所有 Web 部件只能有一个 EAP。

实现请求结果类

  1. 在 Microsoft Visual Studio 2010 中,启动一个空 SharePoint 项目。

  2. 将类项目添加到该项目中。

  3. 将类设置为继承自 SPExternalApplicationRequestResult

  4. 如果不需要客户端哈希,可实现 ClientHash 属性以返回 null。如果希望在发送回外部应用程序的结果中包括客户端哈希,可以专用支持字段(一个 Byte 数组)的包装的形式实现 ClientHash 属性。

    private Byte[] clientHash;
    public override Byte[] ClientHash 
    {
        get { return clientHash; } 
    }
    
  5. 如果使用客户端哈希,可创建一个构造函数,该函数具有一个类型为 SPExternalApplicationRequestProperties 的参数,以及另一个作为字节数组的参数(代表客户端 salt)。在创建客户端哈希值时,此构造函数应将 SPExternalApplicationRequestProperties 对象的 RequestTokenPrefix 属性和字节数组作为输入。字节数组必须是一个由承载外部应用程序的服务器提供的值,并且所使用的算法必须与外部应用程序将用于创建其客户端哈希副本的算法相同。应考虑使用 System.Security.Cryptography 命名空间的类(例如 HashAlgorithmSHA512Managed)。下面是一个示例。若要像此示例那样使用 SHA512Managed 类,必须在代码文件中为 System.Security.Cryptography 命名空间添加 using(在 Visual Basic 中为 Imports)语句。

    public CustomRequestResult() { }
    public CustomRequestResult(SPExternalApplicationRequestProperties externalAppRequest, byte[] clientSalt)
    {
        string prefix = externalAppRequest.RequestTokenPrefix;
    
        int nCount = Encoding.Unicode.GetByteCount(prefix);
        nCount += clientSalt.Length;
        byte[] bytes = new byte[nCount];
        nCount = Encoding.Unicode.GetBytes(prefix, 0, prefix.Length, bytes, 0);
        for (int i = 0; i < clientSalt.Length; i++)
        {
            bytes[nCount + i] = clientSalt[i];
        }
        // Compute the hash value
        SHA512Managed sha512 = new SHA512Managed();
        clientHash = sha512.ComputeHash(bytes);
    }
    

    如果派生类使用的 SPExternalApplicationRequestProperties 的唯一部分是 RequestTokenPrefix 属性,则可以编写构造函数以将 String 作为第一个参数,并且调用代码(以下过程中将讨论的 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 方法)只将 RequestTokenPrefix 属性传递给它。另一种方法是在调用代码构造派生类型对象之前将该调用代码设计为创建客户端哈希。在这种情况下,可以将该类型的构造函数设计为将哈希值本身作为字节数组参数,并立即写入 clientHash 支持字段。

  6. 如果不希望自定义 Web 部件的呈现方式,可实现 GetContentControl(String) 方法以返回 null。但如果要自定义 Web 部件的呈现方式,可实现此方法以返回 Control,该控件是 Web 部件的唯一子控件。它通常是一个包含 HTML 标记的 Literal

实现 EAP 类

  1. 将类项目添加到该项目中。

  2. 将类设置为继承自 SPExternalApplicationProvider

  3. 如果要自定义 SilverlightToolPart 的 UI,可实现 GetRegistrationInformation(SPWeb) 方法。您可以更改此方法返回的 SPExternalApplicationRegistrationInformation 对象的任何五种属性。例如,如果要替换自定义注册页、将自定义页的 URL 分配给 HyperlinkUrl 属性。您可以使用自定义页的内嵌或代码隐藏功能来为用户提供其他服务。例如,您的代码可以读取应用程序 XML 并确定它是否指定了应用程序主体名称。如果是,则代码会确定该应用程序主体用户是否存在,如果不存在,则会创建它。

    下面的示例将注册页上按钮的名称从"配置"更改为"注册",并更改了该按钮的相关说明文字以及它所打开的对话框的大小。此示例还让按钮打开一个自定义可选应用程序注册页。(默认注册页为 newslwp.aspx。)

    public override SPExternalApplicationRegistrationInformation GetRegistrationInformation(SPWeb web)
    {
        SPExternalApplicationRegistrationInformation info = new SPExternalApplicationRegistrationInformation();
        info.Description = "To register a Silverlight application (.xap), click Register";
        info.DialogHeight = 600;
        info.DialogWidth = 500;
        string url = web.ServerRelativeUrl;
        if (!url.EndsWith("/"))
        {
            url = url + "/";
        }
        url += "_layouts/alternateReg.aspx";
        info.HyperlinkText = "Register";
        info.HyperlinkUrl = url;
    
        return info;
    }
    
  4. 如果没有SPExternalApplicationRequestResult 派生类,则可以实现 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 以便仅返回 null。否则,必须确保实现此方法以便构造和使用请求结果类。

    OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 方法由 Web 部件的 CreateChildControls 方法调用。具体而言,CreateChildControls 方法可执行以下操作:

    1. 通过用于注册 Web 部件的外部应用程序 XML 以及有关当前网站的信息构造 SPExternalApplicationRequestProperties 对象。

    2. SPExternalApplicationRequestProperties 对象传递到 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 方法。

    3. 接收 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 方法返回的对象(派生自 SPExternalApplicationRequestResult)。

    4. 使用请求结果对象的 GetContentControl(String) 方法获取 Web 部件的唯一子控件。

    出于安全原因,如果 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 返回 null(就像在内置于 SharePoint Foundation 中的默认 EAP 中一样),则 CreateChildControls 方法需要呈现默认子控件。这是内置 SilverlightWebPartCreateChildControls() 方法所执行的操作。

    因此,实现 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 的主要任务是调用派生自 SPExternalApplicationRequestResult 的类的构造函数,并返回已构造的对象。以下是在开发 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 方法的重写时需要注意的某些事项:

    在下面的示例中,重写的 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 调用名为 CustomRequestResult 且派生自 SPExternalApplicationRequestResult 的类的非默认构造函数。有关此非默认构造函数的详细信息,请参阅本文前面介绍的实现请求结果类这一过程。

    public override SPExternalApplicationRequestResult OnApplicationWebPartCreateChildControls(
           SPExternalApplicationRequestProperties args)
    {
       SPExternalApplicationRequestResult reqRes = CustomRequestResult(args, saltFromApplication);
       return reqRes;
    }
    

向 SharePoint Foundation 标识自定义 EAP 的过程与启用 EAP(如启用外部应用程序提供程序中所述)的过程基本相同。唯一区别是需要为 EAP 类型构造一个对象并将其分配给 ExternalApplicationSettings.Provider 属性,而不是仅启用 EAP。下面是一个示例,其中 ContosoEAP 是派生自 SPExternalApplicationProvider 的类。

ContosoEAP exAppProvider = new ContosoEAP();
SPWebService.ContentService.ExternalApplicationSettings.Provider = exAppProvider;
SPWebService.ContentService.ExternalApplicationSettings.Enabled = true;
SPWebService.ContentService.Update(); 
提示提示

如果已经为 Web 服务启用了外部应用程序管理,则不需要用于设置 Enabled 属性的行,但使用该行也没有坏处。如果以前尚未启用管理,那么包括该行就不需要执行启用外部应用程序提供程序中的相应步骤。但反之则不然:即使使用默认 EAP,也必须执行启用代码的管理过程。

您可以通过所有方法来运行上面启用外部应用程序提供程序中提及的代码行。下面的示例演示如何在 PowerShell 脚本中使用 PowerShell Add-Type cmdlet 运行此代码。

向 Web 服务标识 EAP

  1. 将以下内容添加到某个文本文件中。

    Add-type @"
    using System;
    using Microsoft.SharePoint.Administration;
    
    namespace ContosoCmdlets
    
        public class EAPIdentifier
        {
            public static void IdentifyEAP()
            {
                ContosoEAP exAppProvider = new ContosoEAP();
                SPWebService.ContentService.ExternalApplicationSettings.Provider = exAppProvider;
                SPWebService.ContentService.ExternalApplicationSettings.Enabled = true;
                SPWebService.ContentService.Update(); 
            }
        }
    "@ -Language CsharpVersion3
    [ContosoCmdlets.EAPIdentifier]::IdentifyEAP()
    
  2. 将该文件另存为 EAPIdentify.ps。

  3. 在 PowerShell 窗口中运行该脚本。

创建宿主 Web 部件

如果外部应用程序是 Silverlight 应用程序,则应使用内置 SilverlightWebPart。否则,应从 ClientApplicationWebPartBase 派生新的 Web 部件类。通常,Web 部件具有可编辑的属性,因此还需要为其创建工具部件。

创建 Web 部件

  1. 在 Visual Studio 2010 中,启动一个空 SharePoint 项目。

  2. 将 Web 部件添加到该项目中并打开 cs 或 vb 源代码文件。

  3. Microsoft.SharePoint.WebPartPages 命名空间添加 using 语句(在 Visual Basic 中为 Imports)。

  4. 将 Web 部件类设置为继承自 ClientApplicationWebPartBase,而不是继承自默认 WebPart

  5. 根据需要重写类构造函数、CreateChildControlsRenderContents 方法。

    如果要将 Web 部件用于自定义 EAP,CreateChildControls 方法应执行以下操作:

    1. 调用继承的 GetExternalApplicationRequestResult() 方法。

    2. 调用继承的 GetInitParams() 方法。

    3. 调用通过调用 GetExternalApplicationRequestResult() 返回的 SPExternalApplicationRequestResult 对象的 GetContentControl(String) 方法,并将其作为一个参数传递到调用 GetInitParams() 所返回的 String

    如果没有创建也没有向包含 Web 应用程序的 Web 服务注册任何自定义 EAP,那么上述一系列调用过程将不执行任何操作。

  6. 如果 Web 部件的外部应用程序 XML 包括自定义属性,则必须创建自定义 EAP 来读取这些属性。在创建自定义 EAP 的过程中,需实现 OnApplicationWebPartCreateChildControls(SPExternalApplicationRequestProperties) 方法。有关创建自定义 EAP 的详细信息,请参阅创建自定义外部应用程序提供程序。

  7. 如果 Web 部件具有可编辑的属性,则实现继承的 CreateEditorParts() 方法以便为工具部件类创建一个对象。有关此类的详细信息,请参阅以下过程。

创建工具部件

  1. 将另一个 Web 部件添加到项目中。

  2. 将相关类设置为继承自 EditorPart,而不是继承自默认 WebPart

  3. 添加 SyncChanges() 的实现,以将 Web 部件中的可编辑属性读取到工具部件的可编辑控件中。

  4. 添加 ApplyChanges() 的实现,以从工具部件中的控件读取值并将这些值赋予 Web 部件的属性。

  5. 根据需要重写 CreateChildControls 方法、RenderContents 方法及其他成员。

结束语

SharePoint Foundation 2010 中引入的流体应用程序模型支持将 SharePoint 外部应用程序(包括 Silverlight 应用程序)集成到 Web 部件中,即使这些应用程序使用 SharePoint 数据,但位于 SharePoint 安装域的外部也是如此。

其他资源