SharePoint - 服务器端对象模型

在本章中,我们将了解 SharePoint Server 对象模型。 当您编写将在 SharePoint 上下文中运行的代码时,您可以使用 SharePoint Server 对象模型。 一些常见的示例是页面或 Web 部件中的代码隐藏、功能或列表背后的事件处理程序、计时器作业等。

服务器端对象模型的特征

以下是服务器端对象模型的主要功能

  • 如果您要在 SharePoint 使用的同一应用程序池内编写 ASP.NET 应用程序,则可以使用服务器端对象模型。

  • 如果您正在开发客户端应用程序(例如控制台或 Windows 窗体)或将在 SharePoint 服务器端上运行的 WPF 应用程序,则可以使用服务器端对象模型。

  • 您无法使用服务器端对象模型远程连接到 SharePoint Server。

  • 当您想要使用服务器端对象模型时,请参考 Microsoft.SharePoint 程序集。 还有其他程序集构成服务器端对象模型,但 Microsoft.SharePoint 是主要程序集。

  • 您最常使用的核心类型映射到您作为最终用户使用的组件,因此,网站集、网站、列表、库和列表项等内容由 SPSite、SPWeb、SPList、SPDocumentLibrary 和 SPListItem 类型表示。

  • 表示网站集的类型和服务器端对象模型是 SPSite,表示服务器端对象模型中的 SharePoint 网站的类型是 SPWeb。 因此,当您从最终用户条款转向开发人员条款时,您只需进行心理映射即可。

现在,当您第一次开始使用 SharePoint 时,可能会感到困惑,因为网站超载,并且它在最终用户和开发人员词汇中的含义相反,更不用说 Web 词汇了。

让我们看一个服务器端对象模型的简单示例。

步骤 1 − 打开 Visual Studio 并通过 File → New → Project 菜单选项创建一个新项目。

步骤 2 − 从左侧窗格中的 Templates → Visual C# 中选择"Windows",然后在中间窗格中选择"控制台应用程序"。 输入您的项目名称,然后单击"确定"。

步骤 3 − 创建项目后,在解决方案资源管理器中右键单击该项目并选择 Add → References

控制台应用程序

步骤 4 − 在左侧窗格中选择 Assemblies → Extensions,然后在中间窗格中选中 Microsoft.SharePoint,然后单击"确定"按钮。

现在再次右键单击"解决方案资源管理器"中的项目,然后选择"属性"。

程序集

步骤 5 − 单击左侧窗格中的构建选项卡,然后取消选中首选 32 位选项。

构建选项卡

步骤 6 − 现在返回到 Program.cs 文件并将其替换为以下代码。

using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SharePointData {
   class Program {
      static void Main(string[] args) {
         using (var site = new SPSite("http://waqasserver/sites/demo")) {
            var web = site.RootWeb;
            Console.WriteLine(web.Title);
            var lists = web.Lists;
            
            foreach (SPList list in lists) {
               Console.WriteLine("	" + list.Title);
            }
            Console.ReadLine();
         }
      }
   }
}

注意 − 上面的代码中首先创建了一个新的SPSite对象。 这是一个一次性对象,因此它是在 using 语句中创建的。 SPSite 构造函数接受网站集的 URL,这在您的情况下会有所不同。

var web = site.RootWeb 将获取网站集的根。

我们可以使用 web.Lists 获取列表并打印列表项的标题。

当上面的代码被编译并执行时,你将看到以下输出 −

SharePoint Tutorials
   appdata
   Authors
   Composed Looks
   Contacts
   Course Documents
   Courses
   Documents
   List Template Gallery
   Master Page Gallery
   Site Assets
   Site Pages
   Solution Gallery
   Style Library
   Theme Gallery
   User Information List
   Web Part Gallery

您可以看到这些标题是"解决方案库"、"样式库"、"表单模板"。 这些是 SharePoint 内部使用的列表。 因此,您可能只想显示用户通常会看到的列表,而不是显示所有列表。

因此,我们想要获取所有未隐藏的列表,而不是获取整个列表集合。 我们可以使用链接查询来做到这一点,如下所示。

using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServerObjectModel {
   class Program {
      static void Main(string[] args) {
         using (var site = new SPSite("http://waqasserver/sites/demo")) {
            var web = site.RootWeb;
            Console.WriteLine(web.Title);
            var lists = from SPList list in web.Lists
            where list.Hidden == false
            select list;
            
            foreach (SPList list in lists) {
               Console.WriteLine("	" + list.Title);
            }
            Console.ReadLine();
         }
      }
   }
}

当上面的代码被编译并执行时,你将看到以下输出 −

SharePoint Tutorials
   Authors
   Contacts
   Course Documents
   Courses
   Documents
   Site Assets
   Site Pages
   Style Library

您可以看到,这将为我们返回所有未隐藏的列表。

让我们看一下另一个简单的示例,其中我们还将显示有关列表项的一些信息。

using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServerObjectModel {
   class Program {
      static void Main(string[] args) {
         using (var site = new SPSite("http://waqasserver/sites/demo")) {
            var web = site.RootWeb;
            Console.WriteLine(web.Title);
            var lists = from SPList list in web.Lists
            where list.Hidden == false
            select list;
            
            foreach (SPList list in lists) {
               Console.WriteLine("	" + list.Title);
               var items = list.Items.OfType<SPListItem>().Take(5);
               var isDocLib = list is SPDocumentLibrary;
               
               foreach (SPListItem item in items) {
                  var value = isDocLib ? item.Name : item.Title;
                  Console.WriteLine("		" + value);
               }
            }
            Console.ReadLine();
         }
      }
   }
}

当上面的代码被编译并执行时,你将看到以下输出 −

SharePoint Tutorials
   Authors
      Muhammad Waqas
      Mark Upston
      Allan Bommer
      Andy Onian
   Contacts
      Waqas
      Upston
      Bommer
   Course Documents
      Sample1.docx
      Sample2.docx
      Sample3.docx
   Courses
      SharePoint Tutorials
      C# Tutorials
      ASP.Net Tutorials
      NHibernate Tutorials
   Documents
   Site Assets
   Site Pages
      Home.aspx
      How To Use This Library.aspx
   Style Library

列表数据

当您第一次创建列表时,它始终有一个标题列。 默认情况下,通过此"标题"列可以访问"列表项"上下文或编辑控制块菜单。

由于每个列表都以列标题开头,因此 SPListItem 类型将其公开为属性。 对于并非每个列表都通用的列,您可以通过 SpListItem 类型的索引器访问它们。

您可以向索引器传递几条信息,但最常见的是。 列表设置中的最终用户可以更改此名称。 您不想使用此名称,因为它可能会更改。

第二个是InternalName,它是在创建此列表时设置的,并且永远不会更改。 这是您访问列值时要使用的名称。

让我们看一个简单的示例,我们将检索作者列表,如下所示 −

简单示例

在此示例中,我们将获取作者列表,然后将薪资/费率提高某个值。 因此,对于"薪水/费率"列,我们将使用InternalName

步骤 1 − 转到服务器端资源管理器; 右键单击 SharePoint 连接,然后选择"添加连接..."指定 URL,然后单击"确定"。

SharePoint 连接

步骤 2 − 展开 SharePoint Tutorials → List Libraries → Lists → Authors → Fields → Salary/Rate 字段。 右键单击Salary/Rate并选择属性。 您将在"属性"窗口中看到InternalName

SharePoint 教程

步骤 3 − 下面给出了一个根据 Salary/Rate 检索作者并提高他们的 Salary/Rate 的简单示例。

using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServerObjectModel {
   class Program {
      static void Main(string[] args) {
         using (var site = new SPSite("http://waqasserver/sites/demo")) {
            var web = site.RootWeb;
            var list = web.Lists.TryGetList("Authors");
            if (list == null)
            return;
            var items = list.Items;
            ShowItems(items);
            RaiseRates(items);
            Console.WriteLine("
After Raise
");
            ShowItems(items);
            Console.ReadKey();
         }
      }
      static void RaiseRates(SPListItemCollection items) {
         foreach (SPListItem item in items) {
            var employee = Convert.ToBoolean(item["Employee"]);
            var rate = Convert.ToDouble(item["Salary_x002f_Rate"]);
            var newRate = employee ? rate + 1 : rate + 0.1;
            item["Salary_x002f_Rate"] = newRate;
            item.Update();
         }
      }
      static void ShowItems(SPListItemCollection items) {
         foreach (SPListItem item in items) {
            Console.WriteLine("Salary or rate for {0} is {1:c}", item.Title,
            item["Salary_x002f_Rate"]);
         }
      }
   }
}

在上面的代码中你可以看到我们有两个方法 −

  • 一种是检索名为 ShowItems 的列表,

  • 一种方法是提高费率,称为RaiseRates()

当上面的代码被编译并执行时,你将看到以下输出 −

Salary or rate for Muhammad Waqas is $950.00
Salary or rate for Mark Upston is $15.00
Salary or rate for Allan Bommer is $20.00
Salary or rate for Andy Onian is $870.00

After Raise

Salary or rate for Muhammad Waqas is $951.00
Salary or rate for Mark Upston is $15.10
Salary or rate for Allan Bommer is $20.10
Salary or rate for Andy Onian is $871.00

CAML 查询

在上面的示例中,我们始终使用 foreach 循环多次迭代所有项目,并且始终返回所有列或至少所有列都可访问。

这实际上类似于在 SQL 查询中从表名中执行 select*。

我们可以通过使用所谓的 CAML 查询 来解决此问题。 执行 CAML 查询时,您有两种选择 −

  • 如果您只想查询单个列表,可以使用 SPQuery 对象。

  • 如果您想要查询网站集中的多个列表,则可以使用 SPSiteDataQuery。

通常,当您执行SPSiteDataQuery时,您正在查询特定类型的所有列表。

例如,我想查询所有的联系人列表等。SPSiteDataQuery 允许您确定范围,因此您可以表明您要查询整个网站集,单个网站,或该网站及其所有子网站。

CAML 查询的语法基本上以 XML 格式描述,需要一些时间来习惯构建此类查询。

让我们看一个 CAML 查询的简单示例。 在这里,我们将创建一个 CAML 查询来查询作者列表中的数据。

using Microsoft.SharePoint;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServerObjectModel {
   class Program {
      static void Main(string[] args) {
         using (var site = new SPSite("http://waqasserver/sites/demo")) {
            var web = site.RootWeb;
            var list = web.Lists.TryGetList("Authors");
            if (list == null)
            return;
            var items = QueryItems(list);
            ShowItems(items);
            
            //RaiseRates(items);
            //Console.WriteLine("
After Raise
");
            //ShowItems(items);
            Console.ReadKey();
         }
      }
      static SPListItemCollection QueryItems(SPList list) {
         var query = new SPQuery();
         
         query.ViewFields =
            "<FieldRef Name='Title' />" +
            "<FieldRef Name='Employee' />" +
            "<FieldRef Name='Salary_x002f_Rate' />";
         
         query.Query =
            "<OrderBy>" +
            " <FieldRef Name='Salary_x002f_Rate' />" +
            "</OrderBy>" +
            "<Where>" +
            " <Eq>" +
            " <FieldRef Name='Employee' />" +
            " <Value Type='Boolean'>False</Value>" +
            " </Eq>" +
            "</Where>";
         return list.GetItems(query);
      }
      static void RaiseRates(SPListItemCollection items) {
         foreach (SPListItem item in items) {
            var employee = Convert.ToBoolean(item["Employee"]);
            var rate = Convert.ToDouble(item["Salary_x002f_Rate"]);
            var newRate = employee ? rate + 1 : rate + 0.1;
            item["Salary_x002f_Rate"] = newRate;
            item.Update();
         }
      }
      static void ShowItems(SPListItemCollection items) {
         foreach (SPListItem item in items) {
            Console.WriteLine("Salary or rate for {0} is {1:c}",
            item.Title,
            item["Salary_x002f_Rate"]);
         }
      }
   }
}

我们使用了 CAML 查询来获取一些项目。 在 QueryItems 方法中,您可以看到我们只检索了那些不是 Employee 的项目。

Salary or rate for Mark Upston is $15.10
Salary or rate for Allan Bommer is $20.10