演练:创建一个内容服务对象

上次修改时间: 2009年9月30日

适用范围: SharePoint Foundation 2010

本文内容
ContentService 类文件
ContentLocationCollection 类文件
ContentLocation 类文件
添加自定义操作和 ASPX 页

本演练探讨了如何为自定义服务定义逻辑以便管理 SharePoint Foundation 部署中的站点内容。该示例演示如何创建从 Microsoft.SharePoint.Administration 命名空间中的类派生的类,以在数据库中保留自定义管理设置。该示例包括一些类文件,以实现包含有关位置列表的元数据的数据结构。每个内容位置指定一个必须保留的 URL。

该示例包括为下列类创建代码文件:

  • ContentService 定义顶级对象,该对象派生自 SPService 类,并提供用于管理部署中内容位置的逻辑。此类包含用来初始化 ContentService 对象的构造函数,以及用于检索内容服务及其内容位置集合的成员。

  • ContentLocationCollection 定义一个继承自 SPPerisistedChildCollection 类的集合类,并提供一个包含内容位置的对象。此类包含一个构造函数和一个 Add 方法。

  • ContentLocation 继承自 SPPersistedObject 并定义一个内容位置。此类包括自定义属性设置的构造函数和成员。

除了使用以前的代码文件创建一个程序集外,该示例还演示了如何使用自定义操作功能在"操作"页上添加链接,以便管理员可以访问该服务。另外,该示例还介绍了如何使用自定义 .aspx 页来提供管理内容服务及其内容位置项所需的用户界面。有关在 Microsoft Visual Studio 2005 中创建 SharePoint Foundation 项目的信息,请参阅Getting Started with Programmatically Customizing a SharePoint Web Site in Visual Studio

ContentService 类文件

下面的代码示例定义了一个 FormatType 枚举以及顶级 ContentService 类,该类中包括构造函数和下列成员:

  • Local 一种用来检索当前内容位置服务的静态属性。

  • Locations 一种用来访问内容位置集合的静态属性。

  • GetAllContentLocations 一种方法,用来返回通过该服务提供的所有内容位置。

  • Format 一种用来获取或设置内容服务格式类型的属性。

如以下示例所示,在随后呈现的每个代码文件的顶端都添加了一个指令,以导入 Microsoft.SharePoint.Administration 命名空间。使用 Persisted 属性 (Attribute) 可使属性 (Property) 设置继续保留在数据库中。在该示例中包含对象的自定义命名空间被命名为 MS.Samples.SharePoint.ContentManager。

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports Microsoft.SharePoint.Administration

Namespace MS.Samples.SharePoint.ContentManager

    Public Enum FormatType
        HTML
        XML
    End Enum 'ContentLocationType

    <System.Runtime.InteropServices.Guid("BB69A6EB-3230-43ca-B4F5-752EAC39C74A")>  _
    Public Class ContentService
        Inherits SPService

        <Persisted()>  _
        Private formatType As FormatType

        Private Shared locations As ContentLocationCollection
        Private Shared local As ContentService = Nothing
      
        ' A static property that retrieves the content service. 
        Public Shared ReadOnly Property Local() As ContentService
            Get
                If ContentService.local Is Nothing Then
                    ContentService.local = _
                      SPFarm.Local.Services.GetValue < ContentService > "ContentService"
                End If

                Return ContentService.local
            End Get
        End Property

        ' A static property for accessing the location collection. 
        Public Shared ReadOnly Property Locations() As ContentLocationCollection
            Get
                If Me.locations Is Nothing Then
                    Me.locations = New ContentLocationCollection(Me)
                End If

                Return Me.locations
            End Get
        End Property

        ' An empty public constructor required for serialization. 
        Public Sub New()
        End Sub 'New

        Public Sub New(farm As SPFarm)
            MyBase.New("ContentService", farm)
            ' Add code to initialize as needed. 
        End Sub 'New

        ' A method to retrieve the content location collection. 
        Public Function GetAllContentLocations() As ContentLocationCollection
            Dim service As ContentService = ContentService.Local
            If service Is Nothing Then
                Return Nothing
            End If

            Return service.Locations
        End Function 'GetAllContentLocations

        Public Property Format () As FormatType
            Get
                Return Me.formatType
            End Get
            Set
                Me.formatType = value
            End Set
        End Property 
    End Class 'ContentService
End Namespace 'MS.Samples.SharePoint.ContentManager
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.Administration;

namespace MS.Samples.SharePoint.ContentManager
{
    public enum FormatType
    {
        HTML,
        XML
    }
    [System.Runtime.InteropServices.Guid("BB69A6EB-3230-43ca-B4F5-752EAC39C74A")]
    public class ContentService : SPService
    {
        [Persisted]
        private FormatType formatType;

        private static ContentLocationCollection locations;
        private static ContentService local = null;

        /* A static property that retrieves the content service. */
        public static ContentService Local
        {
            get
            {
                if (ContentService.local == null)
                {
                    ContentService.local = 
                      SPFarm.Local.Services.GetValue<ContentService>("ContentService");
                }

                return ContentService.local;
            }
        }

        /* A static property for accessing the location collection. */
        public static ContentLocationCollection Locations
        {
            get
            {
                if (this.locations == null)
                {
                    this.locations = new ContentLocationCollection(this);
                }

                return this.locations;
            }
        }

        /* An empty public constructor required for serialization. */
        public ContentService()
        {;}

        public ContentService(SPFarm farm)
            : base("ContentService", farm)
        {/* Add code to initialize as needed. */}

        /* A method to retrieve the content location collection. */
        public ContentLocationCollection GetAllContentLocations()
        {
            ContentService service = ContentService.Local;

            if (service == null)
            {
                return null;
            }

            return service.Locations;
        }

        public FormatType Format
        {
            get 
            {
                return this.formatType; 
            }
            set 
            { 
                this.formatType = value; 
            }
        }
    }
}

定义一个自定义 Provision 方法可将 ContentService 对象添加到数据库中,如下例所示。此方法既可包含(也可以不包含)在以前的 ContentService 类中,从而更加模块化并能从不同的上下文调用,例如从可以创建用来安装服务的 Feature 安装程序调用,也可以从命令行操作调用。此 Provision 方法可将 ContentService 对象添加到数据库中,而无需指定程序集和类。

备注

您所定义的自定义 Provision 方法不是 SPPersistedObject 基类的 Provision 方法。

Public Sub Provision()
  ' Add the ContentService administration object to the database.
  Dim contentService As ContentService = ContentService.Local
  
  If contentService Is Nothing Then
    contentService = New ContentService(SPFarm.Local)
    contentService.Update()
  End If
End Sub
public void Provision()
{
    /* Add the ContentService administration object to the database. */
    ContentService contentService = ContentService.Local;

    if (contentService == null)
    {
        contentService = new ContentService(SPFarm.Local);
        contentService.Update();
    }
}

ContentLocationCollection 类文件

下面的示例定义了 ContentLocationCollection 类,该类中包括构造函数和一个用来向集合中添加新内容位置的 Add 方法。

Public Class ContentLocationCollection

  Public Sub New(parent As SPPersistedObject)
    MyBase.New(parent)
  End Sub
  
  Public Sub Add(url As String)
    Dim location As New ContentLocation(String.Empty, Me.Parent)
    
    location.Url = url
    
    location.Update()
  End Sub
End Class
public class ContentLocationCollection : SPPersistedChildCollection<ContentLocation>
{
    public ContentLocationCollection(SPPersistedObject parent) : base(parent)
    {;}

    public void Add(String url)
    {
        ContentLocation location = new ContentLocation(String.Empty, this.Parent);

        location.Url = url;

        location.Update();
    }
}

ContentLocation 类文件

下面的示例定义了一个枚举 ContentLocationType,用来指定内容位置的类型;还定义了一个类 ContentLocation,用来定义内容位置的属性,包括其显示名称、类型、URL 和输出路径。指定 Persisted 属性 (Attribute) 可以使属性 (Property) 设置保留在数据库中。

ContentLocation 类包括以下成员:

  • DisplayName 该属性用于获取位置的显示名称。

  • Url 该属性用于获取或设置内容位置的 URL。

  • LocationType 该属性用于获取或设置位置类型。

  • ContentOutputPath 该属性用于获取或设置输出路径。

Public Enum ContentLocationType
    Web
    List
End Enum 'ContentLocationType

Public Class ContentLocation
  Inherits SPPersistedObject
    <Persisted()>  _
    Private locationType As ContentLocationType

    <Persisted()>  _
    Private contentOutputPath As String

    <Persisted()>  _
    Private url As String

    Public Sub New()
    End Sub 'New

    Public Sub New(name As String, parent As SPPersistedObject)
        MyBase.New(name, parent)
    End Sub 'New

    Public Overrides ReadOnly Property DisplayName() As String
        Get
            Return Me.url
        End Get
    End Property

    Public Property Url() As String
        Get
            Return Me.url
        End Get
        Set
            If Me.url = value Then
                Return
            End If

        Me.url = value

        ' The Name property must be unique among multiple children in a 
        ' collection.  Use the URL to ensure uniqueness. 
         Me.Name = Me.url
        End Set
    End Property
      
    Public Property LocationType() As ContentLocationType
        Get
            Return Me.locationType
        End Get
        Set
            Me.locationType = value
        End Set
    End Property 
      
    Public Property ContentOutputPath() As String
        Get
            Return Me.contentOutputPath
        End Get
        Set
            Me.contentOutputPath = value
        End Set
    End Property
End Class 'ContentLocation
public enum ContentLocationType
{
    Web,
    List
}

public class ContentLocation : SPPersistedObject
{
    [Persisted]
    private ContentLocationType locationType;

    [Persisted]
    private String contentOutputPath;

    [Persisted]
    private String url;

    public ContentLocation()
    {}

    public ContentLocation(string name, SPPersistedObject parent)
      : base(name, parent)
    {;}

    public override string DisplayName
    {
        get
        {
            return this.url;
        }
    }

    public String Url
    {
        get { return this.url; }
        set 
        {
            if (this.url == value)
            {
                return;
            }

            this.url = value;
            /* The Name property must be unique among multiple children in a collection.  Use the URL to ensure uniqueness. */
            this.Name = this.url; 
        }
    }

    public ContentLocationType LocationType
    {
        get { return this.locationType; }
        set { this.locationType = value; }
    }

    public String ContentOutputPath
    {
        get { return this.contentOutputPath; }
        set { this.contentOutputPath = value; }
    }
}

添加自定义操作和 ASPX 页

将 .aspx 页添加到 \Admin 文件夹中,然后在程序集中定义其代码。有关管理 .aspx 页的信息,请参阅管理中心页。可使用功能将自定义操作添加到管理中心页。有关添加自定义操作的信息,请参阅如何:使用自定义操作修改用户界面

下面的 Elements.xml 文件将"内容导出"自定义操作添加到"操作"页(链接到 contentman.aspx 页来管理内容位置)的"全局配置"部分。

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="https://schemas.microsoft.com/sharepoint/">
  <CustomAction
    Id="ContentManagement"
    GroupId="GlobalConfiguration"
    Location="Microsoft.SharePoint.Administration.Operations"
    Sequence="31"
    Title="Content export">
    <UrlAction Url="/_admin/contentman.aspx" />
  </CustomAction>
</Elements>

该自定义操作所指向的 contentman.aspx 文件可以包括指向用于创建、显示或编辑内容位置项的窗体页的链接。例如,"新建项目"页背后的代码可以包括如下逻辑,该逻辑为在页面的 urlImportExport 框中键入的 URL 添加位置项,并能够重定向到 contentman.aspx 页:

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports Microsoft.SharePoint.WebControls
Imports System.Web.UI
Imports System.Web.UI.WebControls

Namespace MS.Samples.SharePoint.ContentManager

    Public Class NewContentImportExportPage
        Inherits Page
        Protected urlImportExport As InputFormTextBox

        Protected Sub SaveNewImportExport(sender As Object, eventArgs As EventArgs)
            Dim service As ContentService = ContentService.Local

            service.Locations.Add(Me.urlImportExport.Text)

            Response.Redirect("/_admin/contentman.aspx", True)
        End Sub 'SaveNewImportExport
    End Class 'NewContentImportExportPage
End Namespace 'MS.Samples.SharePoint.ContentManager
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MS.Samples.SharePoint.ContentManager
{
    public class NewContentImportExportPage : Page
    {
        protected InputFormTextBox urlImportExport;

        protected void SaveNewImportExport(object sender, EventArgs eventArgs)
        {
            ContentService service = ContentService.Local;

            service.Locations.Add(this.urlImportExport.Text);

            Response.Redirect("/_admin/contentman.aspx", true);
        }
    }
}

在实现自定义服务后,可以通过实例化该服务并调用其成员来访问其数据。也可以创建继承自 Microsoft.SharePoint.Administration 命名空间中其他保留对象的其他自定义对象。例如,您可以创建一个从 SPJobDefinition 类派生的类,以通过自定义服务实现计时器作业并执行定时操作。或者,也可以从 SPFeatureReceiver 类继承来定义事件处理,以在服务作为 Feature 安装或激活时注册该服务。

通过保留的对象,可以将自定义管理对象添加到配置数据库中,以保持构建于 SharePoint Foundation 平台之上的 Web 应用程序的逻辑和数据。