ASP.net;sharepoint
c# moss 程序人生
 

这是一篇翻译的文章,该文章的原文地址http://msdn.microsoft.com/en-us/magazine/ee335711.aspx

 

SharePoint 是大型团体的开发解决方案,功能丰富的开发平台。目前的挑战,虽然,总是在创建解决方案和可信任的不会损害和破坏SharePoint场方式下部署解决方案之间找到了平衡。场级管理员有责任维护SharePoint场的健康与健全,意思是进入结构复杂的,费时的进程区域里测试和批准解决方案部署到场中。

这些需求与快捷应用程序模型用于创建SharePoint解决方案时正相反,并且它复杂化第三方解决方案的部署。

SharePoint 2010有一个新功能叫做沙盒解决方案,许多采用沙盒解决方案的企业,可以使场级管理员感觉很舒服,因为采用沙盒解决方案的SharePoint场是安全的,给网站集管理员权限去管理网站集的应用程序,和支持开发人员灵活地创建解决方案,并安全迅速地部署。

这篇文章,描述了SharePoint 2010的沙盒解决方案如何提供安全快速部署解决方案的框架。

你将学习到场级管理员如何监视解决方案和网站集管理员如何安装和管理解决方案和功能。将学习到如何开发沙盒的Web部件。开始理解解决方案如何部署到沙盒里。

 

部署沙盒解决方案

 

沙盒解决方案的结构是非常类似于场的解决方案,一般运行在完全信任的权限下。主要的不同在于沙盒的解决方案如何部署和解决方案(它确定一个解决方案是否是沙盒解决方案还是场的解决方案)宿主的进程。意思是当它部署在场的级别时一些沙盒解决方案可以运行在完全信任的情况下,当它部署在网站集级别上可运行在部分信任的情况下。SharePoint解决方案是可扩展的包,包含功能和程序集。这个解决方案包是基于.cab文件的.wsp扩展包。VS2010 SharePoint项目模板创建.wsp包文件。这个解决方案可包含一些SharePoint功能,和这些功能提供的设计功能如Web部件,列表自定义,模块和事件接收器。现在网站集管理员有权限使用新的解决方案库(沙盒解决方案库)上传,激活,删除和管理沙盒解决方案。这个库也可以使网站集管理员监视资源配额的解决方案的使用。解决方案库是仅仅只是存储.wsp文件的标准SharePoint列表。它位于_catalogs 文件夹下面的_catalogs/solutions里。这个库能添加从Moss2007网站集更新过来的网站。你打开解决方案库,显示下图,首先点击页面上的网站操作,选择网站设置,进入网站设置页面,点击库选项下面的解决方案。即可显示此图。

图 1 SharePoint 解决方案库

 

部署沙盒解决方案非常简单,在网站集中上传.wsp文件到库中并激活它即可。点击解决方案的上传按钮,可以选择上传单个文件或多个文件。接下来,提醒你激活解决方案。当你激活解决方案,网站集范围的功能会自动部署,但你必须到每个网站的管理网站功能页面里激活网站范围的功能,解决方案库的列表有下列字段:解决方案的名称,修改时间,状态,资源使用情况。当你反激活解决方案后就可以从库里删除解决方案。如果你想从网站集里复制解决方案到其他地方,需要保存 .wsp文件到硬盘中然后上传到其他解决方案库里。你也可以使用新的解决方案和功能更新SharePoint2010的基础架构设施功能,然后将新的解决方案和功能更新到沙盒解决方案中。更新解决方案,需要创建新文件名的.wsp文件但是解决方案的ID必须一样。最简单的方式在VS里打开你的项目并修改它,然后用包的设计器更改包名称。在你的解决方案中双击包的节点打开包的设计器,然后更改包的名称。你可以上传沙盒解决方案包作为你的新包。在安装时SharePoint会检测相同解决方案ID并提示你更新。然后你更新完成,你会看到新的版本被激活并且老的版本被反激活,如图2。如果你通过解决方案安装Web部件,你将会看到新的版本在运行

图 2 更新沙盒解决方案

 

编译沙盒Web部件

 

沙盒解决方案的外观和行为像场的解决方案,但沙盒解决方案必须标上允许部分信任调用。在项目的属性窗口中配置沙盒解决方案属性。记住沙盒解决方案可以作为完全信任的解决方案来部署并获取在完全信任的情况下来运行的扩展能力,因为在.wsp解决方案文件没有指定解决方案是沙盒的解决方案还是场解决方案。这种方式决定了解决方案如何部署。

Web部件是最常见的沙盒解决方案类型之一。在这个段落里,描述了如何创建Web部件的沙盒解决方案和指出一些你需要注意的问题。首先,VS有两种Web部件类型---可视化Web部件和标准的Web部件。可视化Web部件包含.ascx控件可以使用设计器查看Web部件。很遗憾的是,不能再沙盒中使用可视化Web部件,因为沙盒解决方案不能部署文件到Web前端上,而.ascx文件必须被部署到Web前端上。因此只能创建标准的Web部件。

新建项目,点击vs菜单栏的文件选择新建项目,弹出新建项目的对话框选择C#VB语言,点击SharePoint选项,选择空项目。当你创建SharePoint解决方案时,项目的向导会询问你是否创建沙盒解决方案,这个选项是默认,一个完全信任的解决方案。看图3。这一选项应用到SharePoint解决方案,那么该解决方案就必须部署到解决方案库里。点击完成后,验证到站点集的路径。

 

图 3 新建SharePoint 项目向导对话框

 

添加Web部件到解决方案中,从项目的主菜单中选择添加项目,然后从列表中选择Web部件项目模板。就有功能齐全的沙盒Web部件,可以部署了。

开发沙盒解决方案之间,当你按F5VS自动部署和激活在解决方案库里的解决方案。如果你浏览解决方案库,你可以看到刚刚创建的解决方案已经部署完成了。在图4中,解决方案库里有默认名为SharePointProject1的解决方案。

图 4  通过VS将SharePoint 项目部署到解决方案库里

 

当你使用VS项目的其他类型时,你可以在沙盒解决方案中设置代码的断点。然而VS不能识别该断点,因为Web部件并没有添加到页面中。你将看到有断点的代码行的左边有一个空心的红圈,这就说明包含Web部件的程序集没有附加到进程中。当你添加Web部件到页面中,VS检测到程序集已经导入并停止在断点上,如图5。即使你没有添加任何代码到项目中,你可以看到一切都就位并且工作正常。

图 5 VS里调试SharePoint 解决方案

 

了解了如何实施SharePoint的沙盒可以帮助你理解如何调试沙盒解决方案。你可能比较熟悉调试完全信任的解决方案,通过SharePoint调用w3wp.exe进程运行在IIS工作平台上。沙盒解决方案不能运行在这个进程中。他们运行在沙盒工作进程里叫SPUCWorkerProcess.exe,你可以看图6。当你按F5的时候VS自动附加调试进程,如果你调试已经部署的解决方案,你需要手动附加这个进程。

图 6 附加SPUCWorkerProcess进程调试沙盒解决方案

 

现在让我们看下面的一组例子,如何在沙盒解决方案中运行代码。首先代码示例工作在沙盒里。添加下列代码到Web部件的CreateChildControls方法里。你可以看到在站点中你访问SPLists集合后返回SPList对象的数量。列表和库一般工作在沙盒解决方案中,因为他们工作在完全信任的解决方案中。在这段代码中,你限制了在当前站点集中。

 

protected override void CreateChildControls()
    {
      base.CreateChildControls();

      Label ListCount = new Label();
      ListCount.Text =
        String.Format("There are {0} Lists",
        SPContext.Current.Web.Lists.Count);
      Controls.Add(ListCount);
    }

 

另一个示例在沙盒里受阻,采用SPSecurity对象工作。剪切和粘贴下列代码到你的Web部件中并部署它到沙盒里:

 

protected override void CreateChildControls()
    {
      base.CreateChildControls();

      SPSecurity.RunWithElevatedPrivileges(
        delegate
        {
          Label ListCount = new Label();
          ListCount.Text =
            String.Format("There are {0} Lists",
            SPContext.Current.Web.Lists.Count);
          Controls.Add(ListCount);
        });
    }

 

你只有当代码执行在沙盒进程中时才能获取异常。异常抛出:“不能导入程序集 'Microsoft.SharePoint, Version=14.900.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c'中的'CodeToRunElevated'类型。”这是一个不安全的异常但丢失类型异常,因为SPSecurity类不是沙盒SharePoint API的一部分,所以它才会触发异常。你应该很想知道为何有丢失类型的运行时异常,是否VS编译解决方案没有任何异常。VS的编译是以SharePoint API的完全版本为标准,但在运行时,SharePoint 交换出全部的API换取沙盒的API,这些API拒绝运行你的代码。当你创建沙盒解决方案时VS能帮你通过过滤的IntelliSense 编写有效的代码。你看图7 SPSecurity类是不会显示在列表里的。显然,如果你从完全信任的解决方案里剪切和粘贴代码,那代码在沙盒中是不会执行的,而VS是不会验证这些的。

图 7 IntelliSense 过滤器帮助你创建有效的沙盒解决方案

 

在沙盒里运行

 

你已经了解了如何部署和编译沙盒解决方案,现在让我们探索一下在沙盒里什么是可以做的。

沙盒解决方案能访问Microsoft.SharePoint命名空间下的大部分功能子集。事实上SPSite下的所有类都是有效的。意思是SPSite, SPWeb, SPList, 和 SPListItem都是有效的。在沙盒解决方案里你可以创建Web部件,列表自定义和实例,内容类型和字段,模块,声明性工作流,和事件接收器。完整的沙盒API文档在SharePoint SDK里。一般来说,当这个站点集部署了沙盒解决方案后,沙盒进程就会阻止你从站点集的外部访问数据。意思是说,例如,你不能通过Internet 调用Web 服务,你不能访问硬盘读写文件,你不能访问没有标示为部分信任调用的代码。在沙盒解决方案中你不能部署文件或添加程序集到GAC中或与安全相关的功能,例如允许RunWithElevatedPriviledges 和其他的SPSecurity 方法,都是不允许的。

但是除了在相同的网站集中读和写列表和库你还能做什么呢。沙盒提供了共享功能编译许多需要一个网站级别的应用程序。有时候,你可能想用沙盒解决方案到沙盒的外部执行信任的操作,例如调用Web服务或访问数据库。最好的方式是通过Business Connectivity Services (BCS)接触到沙盒创建外部的内容类型。然后你就可以从沙盒解决方案里读写数据源。其他或更高级的方式到沙盒的外部,创建一个允许在完全信任的进程里允许的类,在沙盒运行的进程外部去代理调用。代理类部署到场解决方案中,在沙盒解决方案中调用它。

 

监控解决方案

 

场级管理员有责任保持SharePoint场的健康与安全,他们在沙盒解决方案里有监控的工具和设置配额。SharePoint 在管理中心的用户界面中提供了场级管理员给每个网站集分配资源配额。你可以在管理中心的应用程序管理下面访问配额。然后点击网站集下面的配置配额和锁定。你也可以在管理中心站点中直接导航到/_admin/sitequota.aspx。配额和锁定页面,看图8,允许你选择网站集运行。在网站配额信息页面中,你可以设置用户解决方案资源配额属性。你可以允许每天最大使用率和设置磅数。默认是300磅。磅是基于多项因素计算出来的,我们将在稍后做出解释。达到 每天使用率时可以使用电子邮件提醒,达到每天使用率时发送警告电子邮件默认是100磅。页面也会告诉你当前使用率(今天)是多少磅,平均使用率(前14天)是多少磅。这两项提供了相同值时,网站集管理员可以在解决方案库的顶部监视具体的解决方案。

图 8 场级管理员控制资源配额

 

场级管理员也可以使用Windows PowerShell调整解决方案资源配额。例如,PowerShell也可以很轻松地遍历每个站点集和设置他们默认的的返回值。使用Get-SPSite命令和管道,用foreach语句更改每一行代码的所有值。运行下列代码,在开始菜单里打开SharePoint 2010管理控制窗口:

 

Get-SPSite | foreach-object {$_.Quota.UserCodeMaximumLevel = 300}
Get-SPSite | foreach-object {$_.Quota.UserCodeWarningLevel = 100}

 

如果你只想查看当前的配额值,你可以运行下列的PowerShell命令:

 

Get-SPSite | foreach-object {$_.Quota}

 

这些命令为场里的每个网站集输出配额属性。用PowerShell的格式输出网站集简单列表的配额属性,如下:

 

QuotaID                           : 0
StorageMaximumLevel             : 0
InvitedUserMaximumLevel           : 0
StorageWarningLevel             : 0
UserCodeWarningLevel            : 100
UserCodeMaximumLevel            : 300
UpgradedPersistedProperties        :

 

UserCodeWarningLevel 和 UserCodeMaximumLevel是控制沙盒解决方案的两个配额属性。你可以看到在一些管理页面和SharePoint对象模型中条款“用户代码”和“用户解决方案”提到沙盒的代码和解决方案。这些属性允许你去调整分配每个网站集的磅数。你也可以调整被用来计算磅值的算法。磅是基于各种指标计算出来的,设计这些指标是为了监视服务器的资源使用率,以便准确地反映服务器的真实健康状况。SharePoint 包含14个指标有助于配额指标磅值。

 

  1. AbnormalProcessTerminationCount
  2. CPUExecutionTime
  3. CriticalExceptionCount
  4. InvocationCount
  5. PercentProcessorTime
  6. ProcessCPUCycles
  7. ProcessHandleCount
  8. ProcessIOBytes
  9. ProcessThreadCount
  10. ProcessVirtualBytes
  11. SharePointDatabaseQueryCount
  12. SharePointDatabaseQueryTime
  13. UnhandledExceptionCount
  14. UnresponsiveprocessCount

 

每个指标,叫做ResourceMeasure,包含ResourcesPerPoint属性。资源消耗分配了ResourcesPerPoint 值,为了计算该类型使用的磅值。例如,AbnormalProcessTerminationCount 有一个ResourcesPerPoint为1的值。 每时沙盒解决方案异常终止时,会自动添加1磅。如果你想增加沙盒解决方案异常终止,那么你可以将ResourcesPerPoint值设为2。如果你不想关注这些标识可以将值设为0。其他的ResourceMeasures在事件中可能没有一对一的对应关系。CPUExecutionTime指标阻止了沙盒解决方案消耗太多CPU的周期。对CPUExecutionTime来说ResourcesPerPoint的默认值是3600。每次解决方案都能递增地获得AbsoluteLimit的一个磅值。如果解决方案超出了AbsoluteLimit值,即使还没到每天最大使用率它也会被终止。超出AbsoluteLimit的值只会影响单个解决方案,这点不像每天最大使用率。这个两个级别的配额,每日的配额和绝对的限制,一起工作共同保护场的健康。强烈建议不要修改ResourceMeasures,但作为开发人员和管理人员,需要理解这些机制是如何工作的。 虽然SharePoint没提供调整配额指标的管理页面,但你可以通过SharePoint对象模型或Windows PowerShell来查看和修改这些值。下列PowerShell脚本输出了ResourceMeasure对象的14个指标的列表,包含了每个ResourceMeasure对象的所有属性,这个例子输出AbnormalProcessTerminationCount 和CPUExecutionTime这两个值。

 

[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
$spusercodeservice = [Microsoft.SharePoint.Administration.SPUserCodeService]::Local
$spusercodeservice.ResourceMeasures

 

例子输出ResourceMeasure 对象

 

MinimumThreshold              : 0
ResourcesPerPoint              : 1
AbsoluteLimit                        : 1
Name                            : AbnormalProcessTerminationCount
TypeName                          : Microsoft.SharePoint.Administration.SPResourceMeasure
DisplayName                         : AbnormalProcessTerminationCount
Id                             : 878646dd-2460-4e88-83cd-67e938fb069c
Status                           : Online
Parent                           : SPUserCodeService Name=SPUserCodeV4
Version                           : 2308
Properties                          : {}
Farm                            : SPFarm Name=SharePoint_Config
UpgradedPersistedProperties         : {}

MinimumThreshold              : 0.1
ResourcesPerPoint              : 3600
AbsoluteLimit                        : 60
Name                            : CPUExecutionTime
TypeName                          : Microsoft.SharePoint.Administration.SPResourceMeasure
DisplayName                         : CPUExecutionTime
Id                             : 418cbb0f-d191-4633-9177-7a4568d11d8d
Status                           : Online
Parent                           : SPUserCodeService Name=SPUserCodeV4
Version                           : 2265
Properties                         : {}
Farm                            : SPFarm Name=SharePoint_Config
UpgradedPersistedProperties         : {}

 

可以通过SharePoint对象模型编程来调整这些值。可以从静态属性里调用本地的SPUserCodeService对象和遍历ResourceMeasures集合来引用沙盒服务。下面的例子:

 

SPUserCodeService userCodeService =
            SPUserCodeService.Local;

      SPResourceMeasureCollection rmc =
        userCodeService.ResourceMeasures;

      foreach (SPResourceMeasure resourceMeasure in rmc)
      {
        Console.WriteLine(resourceMeasure.Name);
      }

 

在沙盒里验证解决方案

 

SharePoint 沙盒架构为场级管理员提供了另外的一种方式来管理和验证运行在沙盒里的解决方案。当解决方案上传到解决方案库时,场级管理员可以部署解决方案验证器。管理员可以创建验证器,只允许运行特定证书签名的代码,例如,他们可以创建只允许Web部件的验证器。另外很好使用的验证器是当他们激活时场里会记录和分类解决方案。你可以看到这些简单而又强大的工具可以帮助场级管理员获得运行在场里的解决方案句柄。当解决方案被激活时会调用每个解决方案的验证器。如果更新了验证器,那么下次他们在执行时会再次验证解决方案。你可以在SharePoint场功能项目中通过添加一个SPSolutionValidator的派生类来创建验证器。你的验证器类必须将System.Runtime.InteropServices.Guid 属性分配给验证器。你可以使用VS工具栏里添加创建GUID工具来创建GUID的值。这个值是赋给ProviderID属性的。下面你要再构造器中添加UserCodeService的引用。构造器调用基类的构造器,通过UserCodeService和验证器的字符串名称。在构造器里面你必须将“signature" 属性分配该验证器。默认的验证器输出窗体的使用值是1。如果你编译这个示例,你可以使用1234。SharePoint使用signature属性来决定是否验证器已经修改了。在生产的验证器中,你想要一个哈希属性值来包含验证器的版本信息。下面你可以重载ValidateSolution 和 ValidateAssembly 方法。为每个解决方案调用ValidateSolution方法,和在每个解决方案的程序集里调用ValidateAssembly方法。通过SPSolutionValidationProperties对象访问ValidateSolution方法,这个对象包含一系列属性用来验证解决方案。最重要的属性是Valid属性。默认这个属性是设置为False,因此你必须将该属性设置为True否则解决方案将会验证失败。你也可以设置ValidationErrorMessage 和 ValidationErrorUrl属性,发送到后面的信息关于为什么解决方案验证失败,你可以使用文件集合去获取解决方案包里的所有文件的关联。通过SPSolutionFile额外的SPSolutionValidatorProperties 引用ValidateAssembly实例,引用解决方案包的程序集。显示下列解决方案验证器。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.UserCode;

namespace SandboxSolutionValidator
{
  [Guid("DAC77CB7-7511-4E7E-8427-B6A57C5F49F7")]
        class SandboxSolutionValidator:SPSolutionValidator
        {
    [Persisted]
    List<string> PutSomeStringsHere;

    private const string validatorName = "Sandboxed solution Validator";

    public SandboxSolutionValidator(
      SPUserCodeService userCodeService) :
      base(validatorName, userCodeService)
    {
      this.Signature = 1234;
    }

    public override void ValidateSolution(
      SPSolutionValidationProperties properties)
    {
      //System.Diagnostics.Debugger.Launch();
      base.ValidateSolution(properties);
      
      //Determine whether the solution is valid
      properties.Valid = true;

      //Iterate over each file in the solution
      foreach (SPSolutionFile file in
                properties.Files) { }

      //Set the error message and Url if it’s not valid
      properties.ValidationErrorMessage =
        "The solution is not valid";
      properties.ValidationErrorUrl =
        "http://moss.Contoso.com/MyErrorPage.apx";
    }

    public override void ValidateAssembly(
      SPSolutionValidationProperties properties,
      SPSolutionFile assembly)
    {
      //System.Diagnostics.Debugger.Launch();
      base.ValidateAssembly(properties, assembly);

      properties.Valid = true;
    }
        }
}

 

你必须添加解决方案验证器到SPUserCodeService SolutionValidators集合中。你可以通过Windows PowerShell来实现,但推荐使用场级Feature的方式来部署验证器。在功能中,你使用功能接收器将验证器添加到集合中。在FeatureActivated事件中(查看下列代码),你获得了场的SPUserCodeService的关联。你使用SPUserCodeService创建验证器的实例,然后添加实例到UserCodeService的SolutionValidators集合中。这些操作跟调试有所不同,但你可以添加Debugger.Launch的命令到你的代码中。开始VS的实例和附加代码到关联进程。当你完成了部署验证器,你需要移除这些命令。

 

部署验证器

public override void FeatureActivated(
        SPFeatureReceiverProperties properties)
    {
      //System.Diagnostics.Debugger.Launch();

      SPUserCodeService userCodeService =
            SPUserCodeService.Local;

      SPSolutionValidator validator = new SandboxSolutionValidator(userCodeService);

      userCodeService.SolutionValidators.Add(
            validator);
    }

 

使用PowerShell在场里安装验证器,为管理员提供快速验证安装验证器。SharePoint 2010先前的版本中也有默认的解决方案验证器。这个验证器除了设置valid属性值为True不能做别的事。进入下列的PowerShell脚本显示安装验证器的列表。图12显示了输出结果。

 

[System.Reflection.Assembly]::Load(
"Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
$spusercodeservice = [Microsoft.SharePoint.Administration.SPUserCodeService]::Local;
$spusercodeservice.solutionvalidators;

图 12 安装解决方案验证器

 

你已经看到简单的示例,如何在场里创建,部署,和验证沙盒代码。这个示例使你能创建丰富有趣的验证代码,提供便捷而又安全的场。

 

沙盒是默认的

 

正如前面提到的,VS默认的SharePoint项目类型是沙盒解决方案。需要考虑的是创建的解决方案是运行在沙盒环境中的。已经看到沙盒应用程序是很有用的,可以做很多商业用户需要做的任务,提供打破安全的方式下运行。最有用的是你可以将你的解决方案部署到企业中。你不在需要经历痛苦的测试过程和为每个解决方案创建验证,虽然好的软件产品需要遵循。网站集管理员可以控制他们自己的集合并运行他们站点里正确的解决方案。场级管理员将摆脱控制和管理解决方案安装的所有需求的任务,并可以采用一系列丰富监视工具关注整个场的健康状况。最后,预测一下你将看到SharePoint解决方案的剖析。你将看到企业书面解决方案数目的增加,部署,SharePoint社区大幅度地增加,因为解决方案将更容易地访问和轻松地查找,安装和运行。

posted on 2010-05-28 18:10  sumh  阅读(3305)  评论(6编辑  收藏  举报