【转】SharePoint 编程指南

网站相关的对象模型

作为一个应用原型系统,SharePoint提供了很多强大的应用及管理功能,但是,在实际的应用中,这些原有的功能很难满足用户的需求。因此,SharePoint也提供了一套非常完整的对象模型作为底层接口,以此为基础进行二次开发。

Windows SharePoint Services(以下简称WSS)作为SharePoint Portal Server(以下简称SPS)的基础部分,是在开发过程中使用最多的一套体系。因此,在本书开发部分的开始,使用一章的篇幅来介绍WSS的对象模型体系,以及一些简单的应用。

WSS提供了非常完善的一套对象模型体系,大致整个的Web服务器(SPWebServer类)、小到一个文件的版本信息(SPFileVersion类),以及一些网站的设置,都可以通过WSS对象模型来进行访问或修改。此外,为了弥补.NET类库在该环境中的一些不足,在SharePoint中也提供了一些常用的功能的函数,它们被封装在Microsoft.SharePoint.Utilities命名空间中。

通过使用SharePoint的对象模型,可以完成几乎所有的功能,但是在有些时候,由于SharePoint本身的限制(例如严格的权限控制),有一些功能仅使用对象模型是很难完成甚至无法完成的。所以,在考虑用户需求和设计方案的时候,也应该尽可能地考虑到实现的难易程度。

在WSS对象模型体系中,提供了如下一些命名空间(namespace):

·    Microsoft.HtmlTrans.Interface

提供一个接口,用来将文档库中的某些文件以Html的形式显示到客户端,这样在客户端没有安装相应文件的浏览软件的时候,也可以查看这些文件;

·    Microsoft.SharePoint

该命名空间是最常用的一个命名空间,其中提供了WSS中关于网站内容的基本的对象模型,例如网站、列表、文件和用户等,本章也主要是围绕这一命名空间进行介绍;

·    Microsoft.SharePoint.Administration

该命名空间中主要提供了WSS网站管理和参数设置的一些类;

·    Microsoft.SharePoint.Dsp

该命名空间以及之下的几个命名空间提供了一些WSS数据搜索用的接口;

·    Microsoft.SharePoint.Meetings

该命名空间提供了对会议室网站进行操作的一些类;

·    Microsoft.SharePoint.Security

该命名空间提供了WSS中自定义权限管理相关的类;

·    Microsoft.SharePoint.SoapServer

该命名空间提供了关于WebPart和WebPart页相关的WebService类;

·    Microsoft.SharePoint.Utilities

该命名空间提供了一些网站中常用的功能,主要是扩充.NET类库中的一些功能;

·    Microsoft.SharePoint.WebControls

该命名空间提供了一些WSS中特有的Web控件类;

·    Microsoft.SharePoint.WebPartPages

该命名空间提供了Web部件和Web部件页相关的类,其中Web部件(WebPart)是SharePoint开发中一个重点的环节,我们将在第11章中对其进行详细地叙述;

·    Microsoft.SharePoint.WebPartPages.Communication

该命名空间提供了对Web部件通信的支持。

以上这些命名空间和类库封装在Microsoft.SharePoint.dll中。

由于篇幅的关系,在本章中只介绍最基本的一些对象模型的使用,只涉及到Microsoft.SharePoint这一命名空间。其他对象模型的使用方法请参照SDK。

为了便于实现和观察,也便于避开Web环境中一些复杂的机制和权限控制,本章和下一章的示例代码,均使用命令行(Console)方式完成。程序需要直接运行在装有WSS或SPS的服务器上,并且默认操作者具有网站管理员的权限。此外,本章和第10章着重讲解功能和某些注意事项,因此在介绍对象模型的时候,只介绍最常用的一些属性和方法,并且在每部分的最后给出一个示例说明该对象模型的使用方法。更全面的类库、属性和方法的介绍,以及更加详细的示例程序,请参考SDK中对应的章节。

本书中的代码均使用C#语言编写,在WSS或SPS环境中经过测试通过。

在绝大多数的WSS使用场景以及部分SPS的使用场景中,“网站”是使用得最多的一个对象,这是因为在WSS的体系结构中,几乎所有的内容(包括用户、列表、文件系统等)都是依附于网站之上的,这一点在对象模型中也能很明显地体现出来。

在WSS的结构中,网站被划分为Site(网站集)和Web(网站)这两种概念。


 Site和Web的区别与联系

顾名思义,网站集是网站的集合体,在WSS中,Site的主要用处是管理网站,在对象模型中,Site所对应的SPSite除了网站的集合(SPWebCollection)外几乎不包含任何的信息,所有的信息都是储存在Web所对应的SPWeb这一对象模型中的,Web才是真正的内容承载者。

在SharePoint的最初设计理念中,将网站集称为Web,而网站称为Site,这一点从SDK中的SharePoint体系结构图中可以看出来。

但是,在设计对象模型的时候,却又将网站集的对象模型称为SPSite(即SharePoint Site),而网站的对象模型称为SPWeb。因此在SDK的代码示例中经常可以看到例如“SPSite web;”以及“SPWeb site;”这样的变量命名方法,这对于初学者来说是非常容易引起混淆的。

作为开发的参考,为了便于说明,以及和对象模型的统一,本书中所指的Site均为网站集的概念(对应于SPSite),而Web均为网站的概念(对应于SPWeb),请读者注意。


 SPSite的使用

SPSite作为网站集对应的对象模型,其主要的用处是获取某个特定的网站,它最常用的几个功能如下:
„        构造函数
SPSite的构造函数有两种,分别以Site的url和Guid作为参数。
在SharePoint对象模型中,大部分对象都拥有一个Guid作为它唯一的标识符,通过这个Guid可以获取该对象的实例,例如Site(SPSite)、Web(SPWeb)、列表(SPList)、视图(SPView)以及SPS中的区域(Area)、门户列表(AreaListing)等。但也有一些是采用整型作为标识符的,例如列表项(SPListItem)、角色(SPRole)和用户(SPUser)等。
„        AllWebs属性
该属性是一个SPWebCollection类型的变量,通过这个属性,便可以获取到该网站集中的所有网站,包括一个顶级网站和它下面的所有子网站。然后通过以下三种形式之一,便可以得到某个特定的SPWeb的对象:
·      webs[int index]:根据在该集合中的下标获取一个Web;
·      webs[string url]:根据Web的相对url(相对于包含该网站的Site)获取Web;
·      webs[Guid guid]:根据唯一标识该Web的guid获取。
在WSS对象模型中,集合(Collection)是一个比较重要的概念,它实际上是一种对象的存储方式(即.NET框架中集合的概念)。一般来说SPxxxCollection便是SPxxx这个类所对应的集合类,例如SPWebCollection、SPListCollection和SPFileCollection等。但是应该注意到的是,SPSiteCollection并不是包含在Microsoft.SharePoint命名空间中的类,而是在Microsoft.SharePoint.Administration这一命名空间中的,这也说明了Site的主要意义在于网站本身的管理,而非网站内容的管理。
„        RootWeb属性
该属性是一个SPWeb类型的变量,它所对应的对象是该网站集中的顶级网站,通过它可以逐步获得该网站级中的层级结构。(关于顶级网站和子网站的概念,请参考本书中“2.1.2Windows SharePoint 站点架构简介”部分。)
„        OpenWeb函数
该函数返回一个SPWeb类型的变量,通过该函数可以获得该网站集中一个特定的网站。它有以下三种使用形式:
·      OpenWeb():在命令行模式中,该方法返回网站级中的顶级网站对象;但是在网络环境中使用该方法会有不同的效果,详见第11章11.3小节“WebPart编程中的对象模型”;
·      OpenWeb(Guid guid):返回该guid所对应的网站对象;
·      OpenWeb(string url):返回该url所对应的网站对象,注意该url为相对地址(相对于服务器根路径或者网站集根路径)。
【示例9-1】 SPSite的基本使用。
在这个示例中,展示了SPSite的基本用法,包括上面所提到的几个重要功能:
using System;
using Microsoft.SharePoint;
 
namespace WSSModelObject
{
    class Example1_1
    {
        [STAThread]
        static void Main(string[] args)
        {
            // 使用构造函数创建网站集对象
            SPSite site = new SPSite("http://localhost/");
            // 获取根网站信息
            Console.WriteLine("Root:" + site.RootWeb);
            // 遍历网站集中的所有网站
            Console.WriteLine("All Webs in site:");
            foreach(SPWeb web in site.AllWebs)
            {
                Console.WriteLine(web);
            }
            // 打开某个特定的网站
            try
            {
                SPWeb web = site.OpenWeb("subweb1");
                Console.WriteLine(web);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}


在编写程序的过程中,合理地使用try-catch语句是一种良好的编程习惯。SharePoint是一套相对庞大的对象模型体系,在编写程序的过程中,难免会出现预料之外的问题,因此应该尽可能对所有可能出错的语句进行try-catch,如果有必要,捕获每种特定的异常,并提供更加友好的出错信息,使得程序更加人性化。在本书中,为了节省篇幅,除非特殊的需要和说明,在后面的示例程序中一般不进行try-catch处理,请读者注意。
编写SharePoint的程序需要在引用中添加Microsoft.SharePoint.dll,如果是在安装了WSS的机器上,在VS.NET中添加引用界面选择Windows SharePoint Services即可,也可以将dll复制到其他的机器上再引用(但是仍然需要在装有WSS的机器上才能运行),该dll的默认安装路径为:C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\ISAPI。在本书后续章节中除非特殊情况,不再使用完整的代码,而使用代码片段作为示例。
 

SPWeb的使用

在一般的应用场景下,SPWeb是使用最多的一个对象模型,因为几乎所有的WSS的内容都是依附于SPWeb对象的,在编程中也是使用SPWeb来获取其他的对象模型。而获取SPWeb对象的方法在本章9.2.2小节“SPSite的使用”中已经有所提及,就不在这里重复了。

大多数和WSS相关的内容都是通过使用SPWeb的一些成员变量来获取的,这些成员变量主要有:

·      AllUsers:网站内的所有成员,以及通过域组(domain group)来浏览网站的用户;

·      Files:网站下的所有文件;

·      Folders:网站下的所有目录;

·      Groups:所有跨网站用户组;

·      Lists:网站下的所有列表;

·      ListTemplates:网站下的所有列表模板;

·      Permissions:网站下的权限;

·      Roles:网站下的所有角色;

·      Users:属于该网站的所有用户;

·      Webs:该网站的所有子网站。

通过使用这些成员变量,就可以获取到相应内容的对象集合(Collection),进而获取需要的内容。

此外,SPWeb的某些成员变量对应于该网站的一些属性,例如:

·      AllowAnonymousAccess:网站是否允许匿名访问(只读);

·      Author:网站的创建者(只读);

·      Created:网站的创建时间(只读);

·      CurrentUser:当前的用户(只读);

·      ID:唯一标识该网站的Guid(只读);

·      IsRootWeb:该网站是否为顶级网站(只读);

·      ParentWeb:该网站的父网站(只读);

·      Site:该网站所属的网站集(只读);

·      Title:该网站的标题;

·      Url:该网站的url(绝对路径)(只读);

·      WebTemplate:该网站的模板(只读)。

SPWeb对象还提供了一些方法,例如:

·      GetFile:通过url获取一个文件的对象(SPFile);

·      GetFolder:通过url获取一个目录的对象(SPFolder);

·      GetListOfType:获取特定类型的列表的集合;

·      GetSubwebsForCurrentUser:获取该网站的子网站(可以指定模板);

·      GetViewFromUrl:通过url获取一个列表的视图(SPView);

·      SaveAsTemplate:将网站保存为模板;

·      SearchDocuments:搜索网站的文档库(需要开启全文检索功能);

·      SearchListItems:搜索列表条目;

·      Update:使网站属性的修改生效。

在SharePoint的对象模型中,一些比较重要的对象都会拥有Update方法(例如SPWeb、SPList、SPField和SPListItem),在修改这些对象的属性时,只有在调用Update方法之后,这些修改才会真正生效。仅限普通属性,不包括集合类的属性,比如SPWeb.Lists中添加或删除一个列表,不需要调用SPWeb.Update方法。这一点需要特别引起注意 。

【示例9-2】  得到一个网站集中的所有网站,并输出它们的标题、url、父网站及子网站。

SPSite site = new SPSite("http://localhost/");

foreach(SPWeb web in site.AllWebs)

{

    Console.WriteLine("Title: " + web.Title);

    Console.WriteLine("Url: " + url);

    Console.WriteLine("ParentWeb: " + web.ParentWeb);

    Console.Write("SubWebs: ");

    foreach(SPWeb subweb in web.Webs)

        Console.Write(subweb.ToString() + " ");

    Console.WriteLine();

}

一个小技巧:在.NET对象模型中,每个类都会有ToString函数(继承自Object类),一般来说每个类也都会对这个方法进行重写。SPWeb的ToString方法一般情况下就是返回了SPWeb.Title这个属性。在大多数字符串操作过程中,一个对象的ToString方法是可以被隐式调用的(例如示例9-1中就使用了这个特性),在不知道该对象是否为空(null)的时候,如果显式调用ToString方法会造成一个异常(NullReferenceException),但是在隐式调用的时候便不会产生这个异常,如果仅是作为输出的需要,隐式的调用要比显式的调用更加方便。

在示例9-2中,输出每个网站的父网站,但是对于顶级网站来说,其父网站为空,如果显示调用的话,便会出现异常,采用隐式调用就可以避开这个问题,只显示一个空的字符串。

示例9-2中使用了三种输出网站标题的方法:SPWeb.Title属性,隐式调用SPWeb.ToString方法,显式调用SPWeb.ToString方法。

列表相关的对象模型

在SharePoint中,列表(List)是一个非常强大的功能。它可以方便地自定义列表的结构,添加和删除各种类型的字段,也可以设置计算字段和引用字段,也可以设置列表条目的审批功能,同时列表还提供了多种可以自定义的视图,对列表的数据进行筛选或者排序。本节主要介绍列表相关的对象,包括列表(SPList)、列表视图(SPListView)、列表字段(SPField)和列表条目(SPListItem)。


SPList的使用

在使用列表的功能之前,通常都需要首先获取该列表对象,获取SPList的主要方法是通过访问SPWeb.Lists这一SPListCollection类型的属性。从该集合中获得一个特定的列表对象有如下三种方法:

·      lists[string name]:通过该列表的名称获取;

·      lists[Guid guid]:通过唯一标识该列表的Guid获取;

·      lists[int index]:通过列表在该列表集合中的下标来获取

在网站上添加列表,也是通过SPListCollection对象来完成的。添加一个列表通过调用SPListCollection.Add方法来完成,创建成功之后,会返回新列表的Guid。该方法提供了如下三种形式:

·      Add(string title, string description, SPListTemplate template):

前两个参数分别指定列表的名称和简介,第三个参数是一个SPListTemplate型变量,指定该列表创建时所需要的列表模板对象,该对象可以通过SPWeb.ListTemplates属性获得;

·      Add(string title, string description, SPListTemplateType type):

前两个参数指定列表的名称和简介,第三个参数使用SPListTemplateType型枚举指定列表模板,枚举中所包含的都是网站默认拥有的基本类型的列表模板,如果要创建一个自定义的列表,请使用SPListTemplateType.GenericList作为该参数;

·      Add(string title, string description, SPListTemplate template, SPDocTemplate docTemplate):

该方法会创建一个文档库(一种特殊的列表),前两个参数分别指定列表的名称和简介,第三个参数制定列表的模板对象,第四个参数指定文档库的模板对象,该参数是一个SPDocTemplate类型的变量,可以通过SPWeb.DocTemplates属性获得。

删除列表时,通过调用SPListCollection.Delete方法来完成,该方法只有一种形式:

·      Delete(Guid guid):通过列表的Guid删除该列表。

SPList类有如下一些常用的属性:

·      BaseTemplate:该列表所对应的列表模板(只读);

·      BaseType:该列表的基础类型(只读);

·      DefaultView:该列表的默认视图对象(只读);

·      EnableAttachments:该列表是否允许添加附件;

·      EnableModeration:该列表是否开启审批功能;

·      Fields:列表字段的集合(将在下文进行详细介绍);

·      Forms:列表表单的集合,主要有浏览、添加和修改几个页面(只读);

·      ID:标识该列表的唯一的Guid(只读);

·      Items:列表条目的集合(将在下文进行详细介绍);

·      ParentWeb:列表所在的网站对象(只读);

·      Title:列表的标题;

·      Views:该列表的视图的集合(将在下文进行详细介绍)(只读)。

这其中值得注意的是BaseTemplate与BaseType的区别:BaseTemplate是生成列表的模板,例如“链接”和“联系人”等,每个模板中都默认设置了一些独有的字段,该属性为SPListTemplateType型的枚举类型,默认这些模板的字段设置可以在SDK的“Field Tables for Default Lists”一节中找到;它的具体位置为Microsoft Windows Share Point ServicesŽAppendixŽField Tables for Default Lists,而BaseType则是列表的基础类型,例如“讨论区”、“文档库”等,每种基础类型的列表都提供了一些普通列表所不具备的特殊的功能,该属性为SPBaseType型的枚举类型。

修改列表属性后,通过调用SPList.Update方法使修改生效。

【示例9-3】  在该示例中创建一个联系人列表,并显示该列表添加条目页面的url。

// 首先获取到SPWeb对象web

SPListCollection lists = web.Lists;

SPList newList = null;

try

{

    Guid id = lists.Add("DemoList", "这是一个测试列表",

                            SPListTemplateType.Contacts);

    newList = lists[id];

    SPForm form = newList.Forms[PAGETYPE.PAGE_NEWFORM];

    Console.WriteLine(form.Url);

}

catch

{

    Console.WriteLine("列表添加失败");

}


SPView的使用

视图在SharePoint的列表中是一个比较重要的概念,在SharePoint中,列表中所有的数据都是通过视图呈现给用户的,视图中定义了需要显示的字段,以及显示的方式,某一些特殊的列表默认拥有一些特殊的视图将数据呈现出来,例如“任务”模板列表中的“日历视图”,等等。

除了负责数据的多样化显示,视图的另外一个重要的作用就是对数据的筛选和排序,在SharePoint环境中可以直接对视图的这些内容方便地进行修改,通过使用计算字段,可以更加丰富筛选和排序的功能。

获取一个SPView对象有如下几种方法:

(1)通过List.DefaultView属性得到该列表的默认视图;

(2)通过SPWeb.GetViewFromUrl方法根据url获取到该视图,在实际使用中,可以使用这种方法先获得一个视图,再得到这个视图所在的列表的对象;

(3)通过List.Views得到该列表的所有视图,再通过以下三种方式得到特定的视图:

·      views[string name]:通过视图的名称获取;

·      views[Guid guid]:通过唯一标识该视图的Guid获取;

·      views[int index]:通过视图在该视图集合中的下标来获取。

添加一个视图通过调用SPViewCollection.Add方法来完成,该方法有两种形式:

·      Add(string name, StringCollection fields, string query,

         uint rowLimit, bool paged, bool makeDefault):

name参数指定了视图的名称,fields参数指定了需要显示的字段名的集合,query参数指定了对数据的筛选条件,rowLimit参数指定了视图中一次所返回的列表条目的最大个数,paged参数指定了该视图是否支持翻页,makeDefault参数指定了是否需要将该视图作为默认视图;

·      Add(string name, StringCollection fields, string query,

         uint rowLimit, bool paged, bool makeDefault,

·      SPViewCollection.SPViewType type, bool personalView):

前面的参数含义与上文相同,type参数指定了该视图的基本类型,personalView参数指定了该视图是否为个人视图(否则为公共视图)。

需要注意的是,与列表的添加方法不同,视图的添加方法返回的对象是SPView的对象,而不是一个Guid。

删除一个视图同样使用SPViewCollection.Delete方法,用视图的Guid作为参数。

有一点需要注意的是,在使用默认页面浏览一个视图的时候,视图的翻页功能只有“下一页”而没有“上一页”,如果需要实现向前翻页的功能,需要自己编写程序来完成。

SPView中常用的一些属性如下:

·      ID:标识该视图的唯一的Guid;

·      ParentList:包含该视图的列表对象(SPList);

·      PropertiesXml:该视图的基本信息,包括url、名称和类型等(只读);

·      Query:视图中对数据进行筛选的查询xml字符串;

·      SchemaXml:该视图的信息,包括基本信息和例如筛选、分组等的设置(只读);

·      Title:该视图的名称;

·      ViewFields:该视图需要显示的字段的集合;

·      Url:显示该视图所对应的url(只读);

修改视图属性后,使用SPView.Update方法使修改生效。

【示例9-4】  该示例中创建了一个视图,并指定了该视图的一些设置:

// 首先获取到SPWeb对象web

SPList list = web.Lists["ListName"];

SPViewCollection views = list.Views;

 

string viewName = "View_Name";

 

StringCollection viewFields = new StringCollection();

 

viewFields.Add("Field1_Name");

viewFields.Add("Field2_Name");

viewFields.Add("Field3_Name");

 

string query = "<Where><Eq><FieldRef Name=\"Field3_Name\"/>" +

    "<Value Type=\"Text\">Text</Value></Eq></Where>";

 

views.Add(viewName, viewFields, query, 100, true, false);

程序中的StringCollection类是在System.Collection.Specialized命名空间中。

SPField的使用

SPField对应于列表对象中的字段(Field)对象,和传统的数据表一样,SharePoint的列表也是由若干个字段所组成的,每个字段可以设置为不同的数据类型,也可以拥有不同的属性设置(例如默认值、是否隐藏、是否可以为空等)。而SharePoint列表的最大一个特点,就是字段的可定制性,不需要进行任何的编程,也不用深入数据库进行复杂的调整,仅在使用界面上就可以方便地对列表的字段进行添加、删除和修改,这种方便的特性也正是很多用户喜爱SharePoint的一个重要原因。

获得一个SPField对象的方法主要是通过SPList.Fields属性得到所有字段,再通过以下两种方法得到特定字段的对象。

·      fields[string dispName]:根据该字段的显示名称获得

·      fields[int index]:根据该字段在集合中的下标获得。

为列表添加一个字段有三种方法:

·      Add(string dispName, SPFieldType type, bool bRequired)

其中第一个参数指定该字段的显示名称,第二个参数指定该字段的类型,第三个参数指定在填写数据的时候,该字段是否为必填内容。

·      AddLookup(string dispName, Guid lookupListID, bool bRequired)

该方法为列表添加一个特殊的字段——“查阅项”字段,通过第二个参数指定目标列表的Guid,其余两个参数的含义和使用方法与Add方法相同。

·      AddFieldAsXml(string strXml)

通过一段xml的描述添加一个字段,该描述中需要包括字段等信息,实际上,这段xml描述对应于SPField.SchemaXml属性。

需要特别注意的是,以上三种方法所返回的虽然都是string型的变量,但是它们的含义各不相同,Add方法返回的是显示名称,AddLookup方法所返回的是内部名称(这两者的区别稍候会进行介绍),而AddFieldAsXml方法所返回的是一段包含字段名称的xml。

注意

在添加字段时,bRequired参数(对应与SPField.Required属性)指定的是在用户界面中新建、修改列表项的时候,该字段是否为必填内容。但实际上,如果我们通过对象模型来创建或修改一个列表条目的时候,该字段并不会起到任何限制作用。

SPField拥有如下一些比较常用的属性。

·      DefaultFormula:计算字段的公式;

·      DefaultValue:字段的默认值,即该字段在未进行设置时的初始值;

·      Description:该字段的说明描述信息;

·      Filterable:该字段是否可以被筛选(只读);

·      Hidden:该字段是否在列表中显示;

·      InernalName:该字段的内部名称;

·      ParentList:该字段所在的列表的对象;

·      ReadOnlyField:该字段是否被只读;

·      Required:在填写数据的时候,该字段是否必填;

·      SchemaXml:该字段设置的信息;

·      Sortable:该字段是否可以被排序;

·      Title:该字段的字段名,即显示名称;

·      Type:该字段的类型,为SPFieldType类型的枚举。

在SharePoint中,每一个字段都有两个名称,即显示名称(DisplayName)和内部名称(InternalName),它们在对象模型中对应于SPField.Title和SPField.InternalName。其中显示名称是在用户使用界面上看到的名称,虽然该名称在网站使用界面的操作中是不可重复的,但是,在使用对象模型添加字段的时候,或者内部管理的时候,可能会有一些重名的字段(其中典型的代表就是每个列表的“标题”字段);而内部名称是SharePoint列表用于内部管理的名称,它在列表中是唯一的,而且其中没有中文和空格(在保存为内部名称时,对于这些字符会进行编码)。

在编写程序的时候,

在下列情况中必须使用显示名称:

·      使用SPList.Fields["name"]获取该字段对象时,必须通过显示名称。

在下列情况中必须使用内部名称:

·      使用SPView.ViewFields的时候,添加、删除都是通过内部名称,获取的时候也是得到内部名称;

·      使用SPView.Query的时候,必须使用内部名称;

·      使用SPQuery(下面会提到该类)的时候,必须使用内部名称。

在下列情况中即可以使用显示名称,也可以使用内部名称:

·      使用SPListItem["fieldName"]获取或设置列表项某个字段的值。

上面所提到的一些属性是SPField类中的属性,也就是所有字段都拥有的一些属性,而SharePoint对象模型中,也为每一种类型的字段提供了单独的类,例如SPFieldText、SPFieldLookup和SPFieldNumber等,每一个类都有一些该类型的字段所拥有的特殊属性,这些类是SPField的子类,在使用的时候需要通过强制类型转换,将SPField类转换为对应的类型。这些类的具体使用方法由于篇幅原因不在此进行详细地介绍,请参考SDK中的有关内容。

在使用SchemaXml属性的时候,我们会发现除了SPField以及它的子类所包含的一些属性之外,还会有一个“ColName”属性,实际上这个属性是和SharePoint列表实现的具体机制相关的,它保存的是在底层数据库的某个表中存放该字段那一列的名称。关于这一点,会在第12章高级开发中,进行比较详细的介绍。

修改字段的属性后,通过调用SPField.Update方法使修改生效。

【示例9-5】  为列表创建一个NumDemo字段,并指定该字段的最大值和最小值:

// 首先获取到SPWeb对象web

SPList list = web.Lists["ListName"];

 

string fieldName = list.Fields.Add("NumDemo", SPFieldType.Number, false);

 

SPFieldNumber field = (SPFieldNumber)list.Fields[fieldName];

field.MinimumValue = 0;

field.MaximumValue = 100;

field.Update();

该示例中值得注意的是,在列表的字段集合中添加一个字段之后,没有调用list.Update方法,而在对字段本身的属性进行修改之后,调用了field.Update方法。关于对象模型中Update方法的这一点特性已经在本章9.2小节中进行说明了,在此通过示例的方式再次强调一下。

 SPListItem的使用

在列表的实际操作中,最终要接触到的还是作为数据内容部分的列表条目(List Item)。一般来说,在访问列表的某个具体条目之前,都需要先获得一个列表条目的集合,在SharePoint对象模型中,提供了很多种方法来获取列表条目集合:

最直接地获取列表条目的方法为,使用SPList.Items属性,该属性返回列表中的所有列表条目。在需要得到或者遍历所有列表条目的时候,可以使用这种获取列表条目的方法。

如果有目的地要获得部分列表条目,可以使用SPList.GetItems方法,该方法有如下三种形式:

·      GetItems(SPView view)

返回指定视图中的列表条目,通过这种方法可以按照视图中所指定的筛选、排序及其他的条件按照顺序返回列表条目。在返回的条目中,也只有在视图中定义过的可查看字段中的数据才可以访问到。

·      GetItems(SPQuery query)

顾名思义,SPQuery是SharePoint中负责查询列表条目的一个类,通过定义一个查询,可以方便地获取想要得到的列表条目,SPQuery提供了两种构造函数,一种是无参数的,另外一种可以带有一个SPView类型的参数,即在指定的视图上进行二次的查找。SPQuery最核心的一个属性就是Query属性,它是一个字符串的类型,它通过一种特殊定义过的xml形式,即CAML(Collaborative Application Markup Language)的形式描述一个查询的条件,实际上,这个查询字符串和SPView.Query属性是相当的。在SPQuery中,也可以通过ViewFields属性来指定需要查看的字段(如果不加以指定,则查看所有字段)。在本节最后的示例中,将演示SPQuery的用法。

·      GetItems(SPQuery query, string viewID)

指定SPQuery查询和视图,获取列表条目。需要特别注意的是,虽然第二个参数为字符串类型,但是在使用的时候需要传入的是列表视图的Guid,而不是视图的名称,而且该Guid要以一种特殊的形式传入,即两边用“{}”包围起来,全大写形式,这种形式可以通过Guid.ToString("B").ToUpper()方法得到。

在使用SPQuery的时候,必须每使用一次都要重新进行构造(即使用new运算符重新生成一个新的对象),然后再指定Query属性。否则,如果不进行重新构造,即使指定了不同的Query属性,在每次查询的时候始终得到的是第一次指定的Query条件的查询结果。这一点非常容易被忽略。

以上几种方法所返回的都是SPListItemCollection类型的列表条目集合,获得该集合后,在获得某个具体的列表条目时,有下面两种方法。

·      items[int index]:通过在集合中的下标得到该条目,这种方法多在遍历集合的时候使用;

也可以使用SPListItemCollection.GetItemById方法。

·      GetItemById(int id):在SharePoint中,每个列表条目都会有一个在该列表中唯一的id(int型),调用SPListItemCollection类的GetItemById方法,就可以通过该id来得到对应的列表条目。

在得到列表条目之后,就可以对该条目的内容进行访问或修改了,访问条目某个字段的方法最常用的方法为: item[string fieldName],其中fieldName可以使用该字段的显示名称,也可以使用该字段的内部名称。还有一点需要注意的是,该方法所返回的是一个Object类型的变量,如果需要使用该变量的话,必须要对它进行强制类型转换,在转换的时候也要特别注意,如果该条目的该字段没有填写任何内容,那么该返回值是null,如果不加以检查就进行类型转换的话,会引发一个异常(NullReferenceException)。在使用这种方法填写或修改字段数据的时候,除了DateTime类型的数据之外,可以一律使用string类型写入(但是除非特殊需要,不建议使用这种做法)。

审批也是SharePoint列表的一个重要的特色,它允许一个列表条目呈现“已审批、待定、被拒绝”这三种状态,在默认视图中,只显示已审批的条目,在“我的提交”视图和“审批视图”中,可以看到其他的条目。

在SharePoint中,一个列表条目的审批信息并非是保存在某个字段中的,而是在对象模型中对应为SPModerationInformation类,并通过SPListItem.ModerationInfomation属性来访问,该类只有两个属性。

·      Comments:审批意见。即列表管理员进行审批操作的时候所填写的意见。

·      Status:审批状态。该属性为SPModerationStatusType枚举类型,对应三种状态。

需要注意的是,ModerationInfomation这一属性,只有当列表允许审批的时候(即列表SPList的EnableModeration属性为true的时候)才可以取得,否则,该值始终为null。

在使用允许审批的列表的时候,获取列表条目时会有一些不同。使用SPList.Items属性只能获得该列表中状态为“已通过”的那些列表条目,要获得其他条目,则必须通过“我的提交”或“审批视图”这两个视图,使用SPList.GetItems方法来取得。开启了审批的列表都会有这两个视图存在,这两个视图SPView对象的ModerationType属性分别为“Contributor”和“Moderator”,表明属于哪一个审批的视图。

在SPListItem中,还有一些比较常用的属性如下。

·      Attachments:该列表条目的附件集合;

·      File:如果该列表是文档库的话,得到该文件的对象(以上两个属性的使用请参考下一节“文件相关的对象模型”);

·      ID:在该列表中唯一标识该列表条目的整型的id;

·      ModerationInfomation:该列表条目的审批信息;

·      ParentList:该列表条目所在列表的对象;

·      Xml:以Xml的格式返回该列表条目中的所有数据。

在列表条目的内容修改后,通过调用SPListItem.Update方法使修改生效。

添加一个列表条目的方法非常简单,只需要调用SPListItemCollection.Add方法,该方法不需要参数,直接返回一个空的SPListItem对象,通过对该对象对各字段的内容进行修改,再调用Update方法,即可将该条目添加到该列表中。

删除一个列表条目,有两种方法:

·      SPListItemCollection.DeleteById(int id)

通过列表条目的id来删除该条目;

·      SPListItemCollection.Delete(int index)

通过集合中的下标来删除该条目。

在通过Delete方法删除一个列表中的所有条目时,注意必须使用下面这种逆序的循环方法:

int total = items.Count;

for(int i=total-1; i>=0; i--)

    items.Delete(i);

而不能正向的循环,更不能使用foreach循环来进行,在初学者中,这是一个比较常见的错误。请读者自己思考这样做的原因。

在SPListItemCollection类中,还有一个非常有用的方法:GetDataTable方法,即:

DataTable GetDataTable();

该方法可以返回由这些列表条目所组成的DataTable对象,以便将数据绑定到一些显示控件(如DataGrid)上。但是注意当列表中没有条目的时候,该函数返回的是null,而不是一个有效的DataTable对象。

【示例9-6】  通过SPQuery获得Score字段中大于等于60的列表条目,并且在这些条目的标题后加上“(合格)”字符串,然后再另一列表中,添加一个新条目,写入合格人数。

// 首先获取到SPWeb对象web

SPListCollection lists = web.Lists;

SPList scoreList = lists["Score"];

SPList passList = lists["Pass"];

 

SPQuery query = new SPQuery();

query.Query = "<Where><Geq><FieldRef Name='Score'/>" +

    "<Value Type='Number'>60</Value></Geq></Where>";

SPListItemCollection items = scoreList.GetItems(query);

 

foreach(SPListItem item in items)

{

    string title = item["Title"] + "(合格)";

    item["Title"] = title;

    item.Update();

}

 

SPListItem newItem = passList.Items.Add();

newItem["Count"] = items.Count;

newItem.Update();
 


在该例中,为了简化场景,没有考虑到不同人、不同科目的分数问题。另外,这个例子只是为了说明和列表条目有关对象模型的使用方法,在实际的应用场景中,类似于上面这种问题,可以通过视图的筛选、分组和汇总的功能在一张列表中直接完成,而且可以接受多人、多科目这种条件,分别统计每一科的合格人数,不需要进行任何编程,SharePoint中强大的视图功能便可以体现在其中。请读者自己思考视图设置的方法。

文件相关的对象模型

SPAttachmentCollection的使用

在SharePoint的列表中,每个列表条目可以拥有0到多个附件文件(附件功能可以在列表常规设置中开启或关闭),在对象模型中,访问这些附件,则可以使用对象模型中的SPAttachmentCollection类来完成。

使用SPAttachmentCollection.Count属性可以得到该列表条目中附件的个数,使用以下方法,则可以获得每一个附件所在的地址。

·      attachments[int index]:通过下标得到附件的文件名,这些附件实际上也是保存在SharePoint的文件系统中的,它们的url为:“List/Attachments/ItemID/FileName”,自然地,SPAttachmentCollection的对象模型中也提供了这样一个属性来访问这一串地址:

·      UrlPrefix:附件文件的前缀url地址(绝对url)。

附件的添加和删除,和添加、删除文件的方法是一样的。

·      Add(string filename, byte[] data):第一个参数指定文件名,第二个参数指定附件内容的字节流。该文件已经存在的时候,也会返回一个异常。

·      Delete(string filename):根据文件名删除该附件。

与添加、删除文件不同的是,因为附件操作是包含在列表条目的修改之中,所以使用Add方法和Delete方法必须调用SPListItem.Update方法才能使修改生效。为了更直接的对附件进行操作,免除Update这一麻烦,SPAttachmentCollection类中提供了AddNow和DeleteNow两个方法,它们的参数和使用与Add和Delete方法一致,只是调用完之后立刻生效,而不再需要进行Update。

在一个列表条目生成之前,SPListItem中的一切属性都是不可用的,所以在对附件进行操作的时候尤其要进行注意,只能对已有的列表条目进行附件的操作。在添加一个新的列表条目的时候,也必须先执行SPListItem.Update,使之成为已有的列表条目,然后才能进行附件操作。

【示例9-9】  该示例读取DemoList列表第一个列表条目的附件,并将它们保存到本地:

// 首先获取到SPWeb对象web

SPList list = web.Lists["DemoList"];

SPListItem item = list.Items[0];

SPAttachmentCollection attach = item.Attachments;

for(int i=0; i<attach.Count; i++)

{

    String url = attach.UrlPrefix + attach[i];

    Console.WriteLine("正在下载{0}...", url);

    SPFile file = web.GetFile(url);

    FileStream fs = new FileStream(file.Name, FileMode.Create);

    byte[] content = file.OpenBinary();

    fs.Write(content, 0, content.Length);

    fs.Close();

}

注意在该程序中,默认列表DemoList存在,也默认该列表中拥有至少一个列表条目。


文档库

文档库是SharePoint中非常重要的一个功能,它提供了例如签入/签出,结合Microsoft Office在线编辑、版本控制等诸多方便的功能。而在SharePoint的对象模型中文档库也是一个比较特殊的对象。

在SharePoint中,文档库有三种形式:文档库、表单库、图片库。

作为一个特殊的对象,文档库即是一个列表(List),也是一个文件夹(Folder)。这样的特性就意味着文档库既可以通过SPList对象来访问,也可以通过SPFolder和SPFile来访问,它们之间是有着内在联系和明确分工的。

在使用SPList访问的时候,它的“FileLeafRef”(内部名称)字段保存的是文件的文件名,它可以通过定义视图和查询来查找我们所需要的某部分文件。在获得SPListItem之后,也可以通过SPListItem.File来得到该列表条目所对应的文件(SPFile)的对象。但是由于是列表的形式,在获得列表的时候是很按照文件夹的方式去获取的,这个时候就需要结合另外的类来进行操作。

判断一个列表是否是文档库,可以通过判断SPList.BaseType属性是否为SPBaseType.DocumentLibrary来完成。而SharePoint也专门提供了一个SPList的子类——SPDocumentLibrary来访问文档库,在判断一个列表为文档库之后,可以将该对象强制转换为SPDocumentLibrary类型,在该类型中,提供了一个有用的函数:

GetItemsInFolder(SPView view, SPFolder folder):指定一个列表的视图,指定一个文件夹,返回该文件夹内的文件所对应的列表条目集合对象(SPListItemCollection)。

同时,我们也可以通过SPList.RootFolder属性得到该文档库的根目录的对象(注意之前应把SPListCollection.IncludeRootFolder设为true)。

在使用SPFolder和SPFile对象访问文档库的时候,可以方便地获取文档库中的层级结构,也可以得到文件的签入/签出状态和版本控制信息,也可以方便地对文件进行复制、移动和删除的操作。但是仅使用这种方法,却无法获得一个文档的审批状态。

在判断文件夹是否为文档库时,可以通过SPFolder.ContainingDocumentLibrary属性来完成,如果该文件夹在文档库中,那么该属性会返回该文档库所在列表的Guid,可以借此获得列表对象;在判断一个文件是否在文档库中时,使用SPFile.InDocumentLibrary属性即可。在确定一个文件包含在文档库之后,通过SPFile.Item属性就可以得到对应的列表条目对象(SPListItem)。

将SPFolder/SPFile与SPDocumentLibrary结合起来使用,可以充分地发挥SharePoint文档库的强大功能。此外,SharePoint文档库还提供了文档讨论的功能,通过ie的一个ActiveX插件来对每一篇文档进行讨论,在对象模型中也提供了SPDocDiscussion类获得该讨论的部分信息,有兴趣的用户可以参考SDK中的相关章节。

在使用文档库的时候,尤其是在中文SharePoint系统中,特别需要注意的是,要明确“列表名称”和“目录名称”这两个不同的概念,这两者可能是不同的,例如,一个文档库的名称叫做“共享文档”(列表的名称),而它所在的url是“Shared Document”(目录的名称)。在使用SPList和SPFolder的时候,不要将这两者混淆起来。

用户/权限相关的对象模型

权限系统是SharePoint的另一大特点,在WSS中,权限可以划分到列表级,而且SharePoint的权限是详细到代码级别的,称为CAS(Code Access Security),也就是说每一个对象模型中的方法、属性的访问都会涉及到权限的问题。这也是为什么前两章都要使用命令行(Console)方式的程序作为示例,而且直接在服务器端运行的原因(正如本章一开始所说的,默认读者是以管理员的身份在服务器端进行操作)。在这样一种权限的机制上,应该说整个SharePoint环境是比较安全的,除非直接读取底层数据库,否则用户无法获得其权限之外的数据;然而在另一个角度上,这种权限的机制也比较死板,只要数据在用户的访问或修改权限之内,那么使用普通的方法也是无法真正限制用户对数据的访问和修改的。

而在用户系统上,SharePoint可以与AD相结合,通过AD来管理、组织用户,可以说非常灵活和强大。

一般来说,用户系统与权限系统是比较紧密地结合在一起的,SharePoint也不例外。因此,本节将两者结合起来介绍。SharePoint对象模型中与用户/权限相关的类主要有以下三个:SPPermission、SPRole、SPUser。


SPPermission的使用

在SharePoint中,由于权限是深入到代码级别的,在每执行一句代码——尤其是对数据进行修改、对系统进行管理的代码——的时候,都有可能会因为当前执行者的权限不足而引发异常。虽然try-catch能够在事后检测并捕获到大部分这种异常,但是,事前的检测在代码编写的过程中有时也是必要的;而有的时候,也需要根据用户的不同权限显示出不同的信息。用户权限的检测就是通过SPPermission类来完成的。

在介绍SPPermission类之前,有必要先简要介绍一下和权限相关的重要的枚举类型SPRights。在这个枚举类型中,列举了所有WSS网站中所用到的权限,例如创建列表条目、修改列表条目、删除列表条目等。在使用这些权限的时候,可以通过二进制掩模(Mask)的方式,将多个权限进行或(or)操作,得到一个新的包含所有用户指定的权限的SPRights变量,后文中的PermissionMask一般都是通过这种方法获得的。由于篇幅关系,这些具体的权限及其含义就不在此列出了,需要使用的时候,请读者参考SDK中的相关内容。

另外,SharePoint也提供了SPPermissionGroup枚举类型,其中定义了每种角色的PermissionMask,在需要获取角色默认权限的时候,可以直接使用该枚举类型。

权限都是挂靠在某个对象上的(比如网站、列表等),在访问这些对象的权限的时候,可以直接通过SPWeb.Permissions属性和SPList.Permissions属性来获得。获取某个具体的用户、角色的权限的时候,通过以下方法来取得:

·      permissions[SPMember member]

其中SPMember是表示用户的SPUser类、表示角色的SPRole类、表示用户组的SPGroup类的一个父类。通过这种方式,可以获得某个网站(或列表)上,某个用户(或角色)的权限。

添加、删除某个用户的权限的时候,同样通过SPPermissionCollection类的方法来完成:

·      Add(SPMember member, SPRights permissionMask):为某个网站成员(用户或角色)添加permissionMask中指定的权限;

·      Remove(SPMember member):删除指定网站成员的权限;

·      ResetPermissions():按照父网站的权限设置,重置该对象的权限。

在得到一个SPPermission对象之后,可以使用它的一些属性:

·      Member:一个SPMember的对象,即拥有该权限的成员;

·      Parent:一个Object的对象,即拥有该权限的对象(SPWeb或SPList);

·      PermissionMask:具体的权限设置;

·      Xml:以xml形式描述的权限设置。

通过将PermissionMask属性与SPRights枚举中的某些具体权限进行与(and)操作,根据操作结果是否非零,来表明该成员在该对象上是否拥有该权限。

但是,正如本节一开始所提到的,之所以需要检查权限的设置,是因为有一些用户没有权限来进行数据的操作或系统的设置。而上面所涉及到的那些方法和属性所需要的对于权限的控制的权限,显然是“普通用户”所不具备的。好在SharePoint为我们提供了一个“普通用户”也可以执行的方法,用来检测权限,它是SPPermissionCollection中的一个方法:

·      DoesUserHavePermission(SPRights permissionMask)

检测当前的用户是否具有参数中所描述的权限,该方法返回一个bool型的值。在执行某些语句之前,或者在需要针对不同权限用户显示不同内容的时候,通过调用这个方法,就可以明确地知道当前执行这段代码的用户,是否具有某种权限,从而再进行相应的处理。

【示例9-10】  列举某个网站上当前用户的所有权限:

// 首先获取到SPWeb对象web

foreach(SPRights right in Enum.GetValues(typeof(SPRights)))

{

if(web.Permissions.DoesUserHavePermissions(right))

{

    Console.WriteLine(right.ToString());

}

}

读者可以使用不同的网站用户身份登录服务器运行这段代码,观察得到的结果有何不同。


SPUser的使用

SPUser是SharePoint中的用户类,在获取SPUser对象的时候,可以通过SPWeb.Users、SPWeb.AllUsers或者SPRole.Users来得到一个SPUserCollection,再通过以下两种方式得到用户。

·      users[string loginName]:以登录名获取到集合中的用户;

·      users[int index]:以集合中的下标获取到用户。

也可以使用如下方法。

·      GetByID(int id):通过用户id获取某个用户的对象;

·      GetByEmail(string email):通过用户的电子邮件地址获取某个用户的对象。

如果只需要获取到当前用户的话,也可以方便地使用SPWeb.CurrentUser属性。

为某个集合添加、删除用户的时候,使用SPUserCollection类中的方法。

·      AddCollection(SPUserInfo[] users):添加一批用户,其中SPUserInfo是一个简单的结构,其中包含Email、LoginName、Name和Notes这四个属性,属性的含义见SPUser类的属性;

·      Remove(int index):通过集合中的下标来删除集合中的用户;

·      Remove(string loginName):通过用户的登录名来删除该用户;

·      RemoveByID(int id):通过用户的id来删除该用户;

·      RemoveCollection(string[] loginNames):通过登录名删除一批用户。

SPUser有如下几个常用的属性。

·      Email:用户的E-mail地址;

·      ID:在当前Site上,唯一标识该用户的id(int型)(只读);

·      IsDomainGroup:该用户是否是一个域组(只读);

·      IsSiteAdmin:当前用户是否是网站管理员(只读);

·      LoginName:用户的登录名(只读);

·      Name:用户的显示名称;

·      Notes:用户的简要说明;

·      ParentWeb:该用户所在的网站(只读);

·      Roles:该用户在该网站的角色;

·      Xml:该用户信息的xml形式的描述(只读)。

需要值得注意的是,在上述的用户信息中,只有LoginName是唯一的(也是全局唯一的),在不同的网站上,用户可能拥有不同的E-mail、显示名称和简介。

在修改用户的属性之后,需要调用SPUser.Update方法使修改生效。

为用户添加角色的过程,一般而言,是通过在角色中加入该用户来完成的,将在下一部分介绍这一方法。


SPRole的使用

SPRole对应于WSS网站中的用户角色(也称为网站用户组,即Site Group)。首先要特别提醒读者注意的是,该对象模型只能应用于WSS网站中,在SPS网站中使用该对象,则会直接引发错误,并且该错误无法被try-catch所捕获,请特别加以小心。

获取SPRole的对象,一般也是先通过SPWeb.Roles属性或者SPUser.Roles属性得到一个SPRoleCollection对象,再通过以下两种形式得到特定的SPRole。

·      roles[string name]:通过角色的名称获取;

·      roles[int index]:通过集合中的下标获取;

或者使用如下方法。

·      GetByID(int id):通过角色的id获取;

·      GetSpecialRole(SPRoleType type):一般来说,网站会默认的拥有一些特殊的角色(管理员、网站设计者、讨论参与者、读者和来宾),在对象模型中,SPRoleType枚举类型对应这五种已有的角色。该方法可以直接获得这五种特殊的角色之一。

添加、删除角色的时候使用SPRoleCollection中的方法。

·      Add(string name, string description, SPRights permissionMask):添加一个角色,第一个参数指定角色的名称,第二个参数指定角色的描述,第三个参数指定角色所拥有的权限;

·      Remove(int index):通过在集合中的下标删除该角色;

·      Remove(string name):通过角色名称删除该角色;

·      RemoveByID(int id):通过角色的id删除该角色。

SPRole的常用属性如下:

·      Description:该角色的描述信息;

·      ID:在该网站上唯一标识该角色的ID(int型)(只读);

·      Name:该角色的名称;

·      ParentWeb:该角色所在网站的对象(只读);

·      PermissionMask:该角色所拥有的权限;

·      Type:该角色的类型(仅对特殊角色有效)(只读);

·      Users:该角色中的用户的集合;

·      Xml:该角色的xml形式的描述(只读)。

在修改角色的信息后,需要调用SPRole.Update方法使修改生效。

在管理一个角色中的用户的时候,直接使用SPRole的方法(而不是在SPRole.Users属性中进行添加或删除)。

·      AddUser(SPUser user):直接通过该用户的SPUser的对象实例来添加该用户;

·      AddUser(string loginName, string email, string name, string notes):通过用户的基本信息添加该用户;

·      RemoveUser(SPUser user):删除该用户。

【示例9-11】  获取网站中的角色,在不存在当前用户的角色中加入当前用户,然后遍历该角色中的所有用户。

// 首先获取到SPWeb对象web

SPUser current = web.CurrentUser;

foreach(SPRole role in web.Roles)

{

    Console.WriteLine("Role:{0}", role.Name);

    if(role.Type != SPRoleType.Guest)

        try

        {

            SPUser user = role.Users[current.LoginName];

        }

        catch

        {

            role.AddUser(current);

        }

 

        foreach(SPUser user in role.Users)

        Console.WriteLine("\tUser:{0}", user.Name);

}
 


在该示例中,在添加用户的时候排除掉了“来宾”这一角色,这是因为该角色一般只应用在SPS的网站当中,无法将WSS网站中的普通用户加入该角色当中。

 

SharePoint的文件系统同样分为文件和文件夹这两大组成部分,但是与普通的asp.net编程不同的是,SharePoint中的文件和文件夹绝大部分是保存在数据库中的,只有一少部分(“_layouts”目录下的文件)是直接保存在服务器的文件系统中(这些文件默认的路径为:“C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE\ LAYOUTS”)。在一般的程序编写中,极少有需要去访问“_layouts”目录下的文件,而访问其他的文件(包括网页、文档库、图片库等)都需要通过SharePoint的对象模型来完成。本节主要介绍SharePoint文件相关的对象模型SPFolder和SPFile,之后会介绍列表中附件的对象模型SPAttachmentCollection,最后用一定的篇幅对SharePoint中特殊的列表“文档库”进行一些简要地说明。

 

SPFolder的使用

SPFolder是SharePoint对象模型中文件夹相关的类,它的使用方法相对比较简单。获取一个SPFolder的对象可以通过SPFolderCollection使用以下两种方法获得。

·      folders[int index]:通过文件夹集合中的下标来获得;

·      folders[string url]:通过该文件夹的url来获得。

而SPFolderCollection对象一般可通过SPWeb.Folders属性或SPFolder.SubFolders属性来获得。

而在SPWeb和SPList的对象模型中,都有该网站(或列表)所在的根目录的信息,可以直接通过SPWeb.RootFolder属性和SPList.RootFolder属性得到。但是需要特别指出的是,SPList.RootFolder的访问默认是没有开启的,如果想通过这种方法得到一个SPFolder对象,必须先将SPListCollection.IncludeRootFolder属性设为true。

在SPWeb中,也可以使用GetFolder方法来获得该网站中的某个文件夹对应的SPFolder对象。

·      GetFolder(string url):参数为该文件夹所对应的路径(注意不要包含最后的“/”字符)。

文件夹的添加和删除同样是通过SPFolderCollection来完成的。

·      Add(string url):添加一个文件夹,参数为待添加文件夹的url,该函数成功后直接返回一个SPFolder对象;

·      Delete(string url):删除一个文件夹,参数为待删除文件夹的url。

在SPFolder类中,有如下一些常用的属性。

·      ContainingDocumentLibrary:如果该文件夹是包含于一个文档库中的,那么该属性返回标识该文档库列表的Guid。该属性只读;

·      Exists:判断该文件夹是否存在,在获取一个文件夹之后(尤其是通过url的方式获取一个文件夹之后),非常有必要先判断该文件夹是否存在,因为在获取文件夹的时候,文件夹不存在并不会引发异常,而在使用一个不存在的文件夹的时候,必然会引发异常。该属性只读;

·      Files:该文件夹下的所有文件的集合;

·      Name:该文件夹的名称(只读);

·      ParentFolder:它的上一级文件夹的对象(只读);

·      ParentWeb:该文件夹所在网站的对象(只读);

·      ServerRelativeUrl:该文件夹相对于服务器根地址的url(只读);

·      SubFolders:该文件夹下所有子文件夹的集合;

·      Url:该文件夹相对于其所在网站的url(只读)。

SPFolder也提供了两个非常有用的函数。

·CopyTo(string newUrl):将该文件夹复制到参数所指定的url中;

·MoveTo(string newUrl):将该文件夹移动到参数所指定的url中。

【示例9-7】  一个简单的函数,通过递归的方法遍历某文件夹下的层级结构:

void LookupFolders(SPFolder parentFolder, int level)

{

    for(int i=0; i<level; i++)

Console.Write('\t');

    Console.WriteLine(parentFolder.Name);

 

    foreach(SPFolder subFolder in parentFolder.SubFolders)

    {

        if(subFolder.Exists)

            LookupFolders(subFolder, level+1);

    }

}


SPFile的使用

SPFile对应于SharePoint对象模型中的文件,它的使用方法与SPFolder类大致相似。在获取SPFile对象的时候,仍是通过SPFileCollection来进行,形式也与获取SPFolder相同。在SPWeb中,也同样提供了SPWeb.GetFile方法来获取一个文件。

·      GetFile(string url):参数为该文件所在的url。

此外,对于文档库列表中的列表条目来说,也可以通过SPListItem.File来得到该文件的对象(关于文档库,稍候会进一步加以说明)。

在删除文件的时候,同样使用SPFile.Delete方法。

·      Delete(string url):参数为待删除文件的url。

添加一个文件与添加文件夹稍有不同,需要指定文件的内容,并且有如下三种不同的形式。

·      Add(string url, byte[] content):第一个参数指定待添加文件的url,第二个参数中以字节流的方式指定文件的内容。在指定文件url的时候,既可以使用完整的url(需要保证该目录存在),也可以只使用文件名(即添加到当前文件夹中)。使用该方法添加文件的时候,如果该url已经存在一个文件,则该函数会引发一个异常;

·      Add(string url, byte[] content, bool overwrite):与上一种形式不同,这种形式通过第三个参数来指定当文件已存在时,是否进行覆盖。当overwrite为true时,会对重名的文件进行覆盖;否则,如果出现重名的情况,仍然会引发一个异常;

·      Add(string url, byte[] content, SPUser createdBy, SPUser lastModifiedBy, DateTime timeCreated, DateTime timeLastModified):添加文件的时候,根据后4个参数,指定文件的创建者、修改者、创建时间、修改时间。但是在使用这种形式的时候需要注意,该程序的执行者必须为网站的管理员,而且该形式只有在WSS网站上有效(在SPS网站上,该方法会产生一个“Access Denied”错误)。

以上三种方法在创建成功之后均会直接返回一个SPFile类型的对象。

SPFile类中一些属性及其含义如下,这些属性一律为只读的。

·      Author:文件的创建者,是一个SPUser类的对象(关于该类,会在下一节中进行说明);

·      CheckedOutBy:文档库的文件允许进行签入和签出的操作,该属性为签出的用户;

·      CheckedOutDate:文件签出的时间;

·      CheckedInComment:文件签入时的评论内容;

·      CheckOutExpires:文件签出的过期时间;

·      CheckOutStatus:文件签出的状态,

·      Exists:该文件是否存在;

·      IconUrl:SharePoint为每种常用类型的文件都提供了图标,该属性中保存了该图标的图像文件的文件名(并非完整的url),这些图片一般保存在“_layouts/images/”目录下;

·      InDocumentLibrary:表示该文件是否在文档库中;

·      Item:如果该文件在文档库中,那么该属性(SPListItem类)获取该文件在该文档库列表中的列表条目对象;

·      Length:文件的大小(以字节为单位);

·      ModifiedBy:该文件的最后修改者;

·      Name:该文件的文件名;

·      ParentFolder:该文件所在的目录对象;

·      Properties:一个Hashtable型的对象,包括该文件的一些常用属性(例如创建者、创建时间、修改者、修改时间、文件大小、文件的版本等信息);

·      ServerRelativeUrl:该文件相对于服务器根地址的url;

·      TimeCreated:文件创建的时间;

·      TimeLastModified:文件最后修改的时间;

·      Url:该文件相对于其所在网站的地址;

·      Versions:SPFileVersionCollection类的对象,SharePoint的文档库可以支持文档的版本管理和控制,该属性中保存了该文件自创建以来的各个版本,同时保存了各版本的信息。(由于篇幅所限,不再一一列举SPFileVersion类的属性,有兴趣的读者请参考SDK。)

SPFile类中也同样提供了一些方法。

·      CheckIn():将文件签入文档库;

·      CheckOut():将文件从文档库中签出;

·      CopyTo(string newUrl):将文件复制到一个新的url地址中;

·      CopyTo(string newUrl, bool overwrite):将文件复制到新的url地址中,并指定是否覆盖同名文件;

·      MoveTo(string newUrl):将文件移动到一个新的地址中;

·      MoveTo(string newUrl, bool overwrite):将文件移动到一个新的地址中,并指定是否覆盖同名文件;

·      OpenBinary():以byte[]的形式返回该文件的内容;

·      SaveBinary(byte[] content):以参数为内容,保存该文件。

【示例9-8】  该示例中演示了从本地上传文件到文档库的过程:

// 首先获取到SPWeb对象web

SPFolder folder = web.GetFolder("Shared Documents");

if(folder.Exists)

{

    FileStream fs = new FileStream(@"C:\Demo.txt", FileMode.Open);

    byte[] content = new byte[fs.Length];

    fs.Read(content, 0, (int)fs.Length);

    folder.Files.Add("Demo.txt", content);

    fs.Close();

}

else

    Console.WriteLine("Folder Not Exist!");
 


该程序中的FileStream类和FileMode枚举是在System.IO命名空间中。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mr. Kitayuta‘s Technology CodeForces - 505D(并查集+拓扑排序或dfs找环) 题解

题目 Shuseki Kingdom is the world’s leading nation for innovation and technology. There are n cities in the kingdom, numbered from 1 to n. Thanks to Mr. Kitayuta’s research, it has finally become possible to construct teleportation pipes between two ci…

二进制枚举子集 CS Maxor 或运算,DP(SOS)

https://blog.csdn.net/noone0/article/details/78289517 目前没有题目链接。 题意:长度为n的序列a,选出两个元素,其或运算结果的最大值为多少,并求出a[i]|a[j]mx的方案数? n<1e5,0<a[i]<2^17,m<17. 假如最大值为mx,若x|ymx 则x和y肯定为mx的子集.否则或运算结果…

【转】SharePoint 中的编程模型

可以通过多种方式开发针对 SharePoint 平台的应用程序。可以基于以下各项将这些应用程序划分下列组中&#xff1a;用于创建应用程序的工具、用于开发应用程序的编程模型、打包和部署应用程序的方法、将应用程序投入市场的方式以及运行应用程序的设备。 SharePoint 框架 ShareP…

【转】SharePoint 术语表

术语表 术语定义访问控制条目 安全对象的自由访问控制列表 (DACL) 或对象的系统访问控制列表 (SACL) 中的一项。在 DACL 中&#xff0c;该项向用户或组授予权限或者拒绝向用户或组授予权限。在 SACL 中&#xff0c;该项指定审核特定用户或组的哪些安全事件或者控制对象的 Wind…

【HDU - 5890】Eighty seven(bitset优化背包)

题干&#xff1a; Mr. Fib is a mathematics teacher of a primary school. In the next lesson, he is planning to teach children how to add numbers up. Before the class, he will prepare NN cards with numbers. The number on the ii-th card is aiai. In class, eac…

【HDU - 1937 】Finding Seats(二维前缀和+尺取法)

题干&#xff1a; A group of K friends is going to see a movie. However, they are too late to get good tickets, so they are looking for a good way to sit all nearby. Since they are all science students, they decided to come up with an optimization problem …

【POJ - 1459】Power Network(网络流最大流,建图)

题干&#xff1a; A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be supplied with an amount s(u) > 0 of power, may produce an amount 0 < p(u) < p max(u) of power, may …

【转】React Vue MVC MVVM MVP

首先&#xff0c;在谈这个话题之前&#xff0c; 我们有必要了解一下库和框架的区别。 我们先来看react官网以及vue官网对他们的定位&#xff1a; react: vue: react我们不说了&#xff0c;官网上明明白白说了&#xff0c;人家是一个library&#xff0c;用于构建用户界面。 v…

**【POJ - 3122】 Pie(二分寻值)

题干&#xff1a; My birthday is coming up and traditionally Im serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should b…

【转】IsCallBack属性和IsPostBack属性有什么区别?

if (Page.IsCallback) return; 此句话在page的构造函数中使用&#xff0c;不让page反复生成。比如一个TEXTbox如果不组织页面刷新&#xff0c;其数据会丢失。 以postback方式进行客户端和服务器端的交互的&#xff0c; IsPostBack就是true。 以callback方式进行客户端和服务器…

【转】使用Feature导入WebPart

原文链接&#xff1a;http://www.cnblogs.com/glife/archive/2009/10/27/1590488.html 前些天在刚刚接触WebPart的时候&#xff0c;搜到了一篇《使用Feature导入WebPart》的文章&#xff0c;那个时候对Feature的了解还为零&#xff0c;所以看了是一知半解&#xff0c;等到今天…

【HDU - 5017】Ellipsoid(爬山算法,模拟退火,三分)

题干&#xff1a; Given a 3-dimension ellipsoid(椭球面) your task is to find the minimal distance between the original point (0,0,0) and points on the ellipsoid. The distance between two points (x 1,y 1,z 1) and (x 2,y 2,z 2) is defined as Input There a…

【转】[SharePoint 开发详解] 一个Feature中使用SPGridView的几个Tips

根据上面一篇随笔所介绍的PC购买流程的项目&#xff0c;在项目中&#xff0c;需要有一个生成订单的功能&#xff0c;能够使得Admin很方便的在获得批准的申请中选取一些来生成订单&#xff0c;要求界面操作简单明了&#xff0c;大概的效果图如下&#xff1a; 点击checkbox&#…

【LeetCode - 131】分割回文串(dp,dfs)

题目链接&#xff1a;https://leetcode-cn.com/problems/palindrome-partitioning/ 题目&#xff1a; 给定一个字符串 s&#xff0c;将 s 分割成一些子串&#xff0c;使每个子串都是回文串。 返回 s 所有可能的分割方案。 示例: 输入: "aab" 输出: [ ["a…

【转】VSTS中版本控制系统Git与TFVC的区别

VSTS&#xff08;Visual Studio Team Services&#xff09; VSTS简单说就是微软TFS(Team Foundation Services)的升级云版&#xff0c;不用像TFS需要在企业内部服务器上部署&#xff0c;并且是免费提供给用户使用的。 每个有微软账号&#xff08;也是免费注册的&#xff09;的…

【LeetCode - 1254】统计封闭岛屿的数目(dfs,连通块)

题目链接&#xff1a;https://leetcode-cn.com/problems/number-of-closed-islands/ 有一个二维矩阵 grid &#xff0c;每个位置要么是陆地&#xff08;记号为 0 &#xff09;要么是水域&#xff08;记号为 1 &#xff09;。 我们从一块陆地出发&#xff0c;每次可以往上下左…

【转】0.SharePoint服务器端对象模型 之 序言

对于刚刚开始接触SharePoint的开发人员&#xff0c;即使之前有较为丰富的ASP.NET开发经验&#xff0c;在面对SharePoint时候可能也很难找到入手的方向。对于任何一种开发平台而言&#xff0c;学习开发的过程大致会包括&#xff1a;开发工具的使用、开发手段的选择和开发语言的编…

【LeetCode - 122】买卖股票的最佳时机 II(贪心 或 dp)

题目链接&#xff1a;https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ 给定一个数组&#xff0c;它的第 i 个元素是一支给定股票第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票…

【转】1.SharePoint服务器端对象模型 之 对象模型概述(Part 1)

在一个传统的ASP.NET开发过程中&#xff0c;我们往往会把开发分为界面展现层、逻辑业务层和数据访问层这三个层面。作为一个应用开发平台&#xff0c;SharePoint是微软在直观的开发能力和自由的扩展能力之间&#xff0c;取到的一个平衡点&#xff0c;其对象模型的设计理念也反映…

【LeetCode - 123】买卖股票的最佳时机 III

题目链接&#xff1a; 给定一个数组&#xff0c;它的第 i 个元素是一支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。 注意&#xff1a;你不能同时参与多笔交易&#xff08;你必须在再次购买前出售掉之前的股票&#xf…