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

本主题概述创建自定义外部应用程序提供程序 (EAP) 的过程。

上次修改时间: 2010年4月8日

适用范围: SharePoint Foundation 2010

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

  • SPExternalApplicationRequestResult – 在以下两种情况下需要实现从 SPExternalApplicationRequestResult 派生的类:

    • 装有外部应用程序的站点和请求转发器要求从 Microsoft SharePoint Foundation 接收的所有结果包含请求转发器可以验证的客户端哈希,以确保结果没有被篡改。

    • 您希望更改 SilverlightWebPart 或某个承载非 SharePoint 应用程序的自定义 Web 部件的呈现方式;例如,您希望在 Web 部件周围呈现自定义部件版式。

  • SPExternalApplicationProvider – 需要在以下任一情况下实现此类:

    • 需要实现从 SPExternalApplicationRequestResult 类派生的类(请参阅上文)。

    • Web 部件的外部应用程序 XML 包含需要读取和处理的自定义标记。

    • 您希望在创建 Web 部件的子控件时运行特殊逻辑。

    • 您希望自定义 SilverlightToolPart 的 UI,或更改在单击工具部件上的"配置"按钮时打开的应用程序注册页。

重要注释重要信息

在考虑是否创建自定义 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; } 
    }
    
    Private clientHash_Renamed() As Byte
    Public Overrides ReadOnly Property ClientHash() As Byte()
        Get
            Return clientHash_Renamed
        End Get
    End Property
    
  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);
    }
    
    Public Sub New()
    End Sub
    
    Public Sub New(ByVal externalAppRequest As SPExternalApplicationRequestProperties, ByVal clientSalt() As Byte)
        Dim prefix As String = externalAppRequest.RequestTokenPrefix
    
        Dim nCount As Integer = Encoding.Unicode.GetByteCount(prefix)
        nCount += clientSalt.Length
        Dim bytes(nCount - 1) As Byte
        nCount = Encoding.Unicode.GetBytes(prefix, 0, prefix.Length, bytes, 0)
        For i As Integer = 0 To clientSalt.Length - 1
            bytes(nCount + i) = clientSalt(i)
        Next i
        ' Compute the hash value
        Dim sha512 As New SHA512Managed()
        clientHash = sha512.ComputeHash(bytes)
    End Sub
    

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

  6. 如果不需要自定义 Silverlight Web 部件的呈现方式或不需要自定义某些承载非 SharePoint 应用程序的自定义 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;
    }
    
    Public Overrides Function GetRegistrationInformation(ByVal web As SPWeb) As SPExternalApplicationRegistrationInformation
        Dim info As New SPExternalApplicationRegistrationInformation()
        info.Description = "To register a Silverlight application (.xap), click Register"
        info.DialogHeight = 600
        info.DialogWidth = 500
        Dim url As String = web.ServerRelativeUrl
        If Not url.EndsWith("/") Then
            url = url & "/"
        End If
        url &= "_layouts/alternateReg.aspx"
        info.HyperlinkText = "Register"
        info.HyperlinkUrl = url
    
        Return info
    End Function
    
  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 部件的唯一子控件。

    图 1: CreateChildControls 方法进行的调用。

    Silverlight Web 部件 CreateChildControls

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

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

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

    public override SPExternalApplicationRequestResult OnApplicationWebPartCreateChildControls(
                SPExternalApplicationRequestProperties args)
    {
        SPExternalApplicationRequestResult reqRes = CustomRequestResult(args, saltFromApplication);
        return reqRes;
    }
    
    Public Overrides Function OnApplicationWebPartCreateChildControls(ByVal args As SPExternalApplicationRequestProperties) As SPExternalApplicationRequestResult
            Dim reqRes As SPExternalApplicationRequestResult = CustomRequestResult(args, saltFromApplication)
            Return reqRes
    End Function
    

向 Web 服务标识 EAP

向 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(); 
Dim exAppProvider As New ContosoEAP()
SPWebService.ContentService.ExternalApplicationSettings.Provider = exAppProvider
SPWebService.ContentService.ExternalApplicationSettings.Enabled = True
SPWebService.ContentService.Update()
提示提示

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

您可以通过任何方法来运行上面的如何:启用外部应用程序提供程序中提及的代码行。下面的示例演示如何在 Windows PowerShell 命令行接口脚本中使用 Windows 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. 在 Windows PowerShell 窗口中运行该脚本。