RSS
 

托管元数据(2)——托管元数据和搜索中的精简面板

22

精简面板(Refinement Panel,SharePoint也有些地方把Refinement翻译成“优化”)是SharePoint 2010搜索中新增加的一个非常好的功能,可以通过搜索结果中的文件类型、作者、修改时间、网站等属性,对搜索结果进行二次过滤,方便用户快速找到自己想要的功能。

2010搜索结果页面中的精简面板是一个Web部件,而且是允许用户进行自定义的,管理员可以随意增加需要在这里进行“过滤”的属性。关于如何在精简面板Web部件中添加自己需要的属性,玉树临风的kaneboy童鞋在这篇博客(点我点我)中已经解释得非常清楚了。这篇博客主要介绍一下托管元数据这种特殊类型的属性在SharePoint搜索结果精简面板中的表现。

如果我们使用默认的Web部件设置,通过点击Web部件属性,在“优化”属性分组中,我们可以看到SharePoint默认使用的优化参数设置。在默认设置的这一段Xml里面,除了文件类型、网站、作者、修改时间之外,我们会看到最后包含两个属性:

1、Title(标题)为“Managed Metadata Columns”、Type(类型)为“Microsoft.Office.Server.Search.WebControls.TaxonomyFilterGenerator”、MappedProperty(映射属性)为“ows_MetadataFactedInfo”

2、Title为“标记”(在英文版中是“Tags”)、Type与第一个相同,MappedProperty为“ows_MetadataFacetInfo, popularsocialtags”

这两个就是SharePoint默认设置中针对托管元数据的处理。它和其它的属性过滤的方式非常不同,而且这种区别不仅仅表现在Type的不同上。

“Managed Metadata Columns”是针对所有已经被配置为可以在搜索结果中进行优化过滤的托管元数据映射属性,只要配置“一切正常”的话,SharePoint会自动从搜索结果中找到这些托管元数据的属性,并且按照不同的来源字段,呈现出多种不同的属性过滤。它的MappedProperty必须设置为“ows_MetadataFacetInfo”,这样SharePoint才能够按照托管元数据的方式对其进行处理(后面会说明SharePoint针对托管元数据属性的处理和对文本类型属性的处理的不同之处);其次,这个看似奇怪的Title是不能随意修改的,只有把它设置为“Managed Metadata Columns”,SharePoint才会去寻找搜索结果中的所有已配置为可优化的托管元数据字段类型,如果我们只需要针对某个字段进行过滤,可以把Title设置成这个字段的名称(显示名称),而任何其他的设置,都会导致这个配置无效。

“标记”(Tags)是针对所有未在上一个节点中出现的其他托管元数据类型的数据的过滤(包括企业关键字、用户标签)。它的MappedProperty设置同样是不可修改的,而且Title也是不可修改的。

 

BUT!

有些时候,虽然是一个托管元数据类型的字段,它并不会按照字段的名称出现在精简面板中,而是一律出现在“标记”这个面板中,如下图所示:

p5

在我进行配置过的几个环境中,只有在我自己的开发虚机中自动根据字段的名称出现了正常的样式(而且这个虚机的多个托管元数据类型的字段,只有一个会出现),如下图所示:

p1

后来经过多次试验(期间改过多种配置,重新进行过多次完全爬网……),后来发现了一个可能的问题:

当我们进行完全爬网的时候,貌似SharePoint会针对每个托管元数据字段自动创建一个映射属性,这些映射属性的名称都是以owstaxId开头的,后面跟着这个字段的名称(应该是内部名称),下面这张图是我开发虚机里面的映射属性的一个截图:

p6

如果仔细看一下的话,就知道为什么只有“知识分类”这个托管元数据字段会“正常”地出现在搜索结果的精简面板中了,它的第三个设置是“是”,其他所有托管元数据字段的设置都是“否”,而这个设置,就是是否允许此映射属性在精简面板中进行过滤,具体的属性设置如下图所示(红框圈起来的那个):

image

在我的另一个项目虚机里面,当我把这个owstaxIdxxxxx的这个设置开启之后,它在精简面板中就可以正常显示了(不过我在做试验的时候,还修改过其他配置,比如爬网账号、托管元数据的各级管理员、甚至手动给这个字段添加了一个映射属性,我不是100%地确定这些设置是否和这个问题有关系,但是只有当我把这个taxId的属性修改了之后,才一切正常)。

如果在你的环境里面,托管元数据类型的字段不能正常出现在搜索结果精简面板中的话,可以按照本文介绍的内容来配置一下。

 

最后,介绍一下SharePoint对托管元数据的“过滤”处理,和一个普通的文本类型属性的过滤处理有何不同。

我们可以尝试按照kaneboy那篇博客中的方法,把一个托管元数据的字段,添加一个“文本”类型的映射属性,并且修改默认的精简面板,添加这个属性(注意Type使用ManagedPropertyFilterGenerator,而不是TaxonomyFilterGenerator)。这种配置方法,在某些情况下,确实是可以按照我们的预期进行工作的,但是它主要的区别在于如下两个方面:

1、对于多值的处理。即使我们在创建映射属性的时候,选择了“具有多个值”,在精简面板中也不会真正地进行多值处理,只会把所有值拼合在一起,作为一个值进行过滤(比如在精简面板中会变成“分类1; 分类2;”,而不是“分类1”和“分类2”两个过滤条件)。

2、对于层级结构的处理。如果是按照本文前面的部分配置的托管元数据类型的过滤器,会按照托管元数据的层级结构进行过滤。举个例子来说,如果我们的搜索结果中某个字段的值有如下几种:猫、波斯猫、孟买猫(其中“猫”是后两者的父级),那么这三个值都会出现在精简面板中,如果我们在精简面板中选择了“猫”的时候,搜索结果中所有标记为“猫”的,以及所有标记为“猫”的所有后代节点的结果,都会被过滤出来。而如果我们是作为一个文本类型的字段进行处理的时候,选择“猫”时,就只会过滤出被标记为“猫”的那些结果,而不会出现被标记为“波斯猫”、“孟买猫”的那些结果了……

其实这两个区别背后的原因,应该是针对不同的字段进行的设置,一个是表面的字段(就是我们存放托管元数据那个类型的字段),一个是背后的字段(注意看上面那张截图中,映射的实际字段是“ows_taxId_KBCatalog”,而不是“ows_KBCatalog”)。

我折腾这个问题的时候,google了很多文章,不过似乎没有谁提到过这个背后的“taxId”字段的那个精简设置的属性。

参考链接:

1、精简面板的设置参考(来自MSDN)

2、在列表定义中创建托管元数据类型字段时需要的一些额外设置(里面提到了一些精简面板的问题,看了这篇blog我才注意到一个托管元数据字段的背后居然有这么多个辅助字段)

btw,春节快乐!

 
 

托管元数据(1)——隐藏列表以及一些相关问题

20

托管元数据服务(Managed Metadata Service)是SharePoint 2010新加入的一个服务(其实我们在2007上自己做过一个类似的自定义字段),关于这个服务的介绍应该就不用再多说了,关于编程访问托管元数据、托管元数据字段的方法也有很多博客都介绍过了(包括中文的),也不再废话了。

这篇Blog主要是介绍一下托管元数据背后的隐藏列表,以及因为这个隐藏列表所带来的一些问题。

如果我们去看一下托管元数据字段类型(TaxonomyField)的继承关系,我们会发现TaxonomyField是继承LookupField的,换句话说,托管元数据在本质上是个查阅项,它查阅的是网站集根网站上,一个名字叫TaxonomyHiddenList的隐藏列表(没错,查阅项是可以跨网站查阅的,从2007的时候就可以,只不过微软没有开放设置界面而已,用代码可以创建出来跨网站的查阅项)。

这个隐藏列表保存了所有在网站集中正在使用以及使用过的所有托管元数据的值(包括企业关键字,这也是个托管元数据类型的字段),当我们在托管元数据字段中选择了某个值并保存之后,SharePoint会判断这个隐藏列表中是否包含这个值,如果不包含的话,会自动把这个值加到列表里。此外,SharePoint在后台有一个TimerJob去把托管元数据服务中的数据同步到这个隐藏列表中(比如改了名字、换了路径、删除之类的)。

自然,这样的设计提供了托管元数据在网站集中的缓存,本意上是在一定程度上提高了性能。但是因为这个背后隐藏列表的存在,以及这种随用随加的机制,导致了一些问题。目前遇到的有如下三个可能存在的问题或不方便之处:

1、权限问题

这种问题出现的可能性不大,不过确实在实际的客户那里遇到过。

TaxonomyHiddenList是不继承网站权限的,他默认的权限设置是所有用户有读取权限(如果你是Windows认证的网站的话,这里的所有用户是Authenticated Users这个AD组),系统账号拥有完全控制权限,如果网站开启了匿名的话,匿名用户拥有查看项目的权限。这样的设置即保证了用户能够正常读取到其中的值,也能够防止其他用户修改列表中的内容(针对这个列表的所有修改都是通过托管元数据服务以及后台的TimerJob来完成的)。

但是上次在客户现场遇到过一个问题,这个Authenticated Users的权限不知道因为什么原因被去掉了,于是就造成了如下的诡异现象:

(1)用户可以在托管元数据导航的地方看到完整的元数据信息,但是点击进行筛选的时候报错(除非系统账号之前点过)

(2)用户在视图、查看页面上看不到任何托管元数据的值,但是在编辑页面和新建页面都能够正常看到。

这个很明显就是用了查阅项、而且查阅的那个列表上没有权限的现象;而新建、编辑、托管元数据导航之所以正常,因为这些数据都是直接来自托管元数据服务的。系统账号点过之后就可以用,估计是因为有缓存神马的。

2、视图筛选

如果你想在一个托管元数据字段上设置视图的筛选条件,那么你就只能使用“等于”和“不等于”这两种运算符,而且这两种运算符都会把托管元数据字段退化成一个“单行文本”行为的字段,换句话说,只能筛选到特定的那一个值,而不包含其中的子项的值。

举个例子来说,如果有下面一个托管元数据字段的设置:

动物;动物/猫;动物/猫/波斯猫;动物/猫/孟买猫;动物/狗;动物/狗/哈士奇;动物/狗/雪纳瑞

如果你想筛选这个字段的值 = 波斯猫的,那么ok,因为波斯猫是处于叶子结点的位置;但是如果你想通过视图去筛选所有的猫,这个是实现不了的。

你会说,如果我用API或者PowerShell设置视图的Query属性,把所有可能的值都包含进去(2010在CAML查询中新提供了一个In的运算符,行为就和SQL里面的In是一样的)呢?

如果你用文本的话,如果管理员修改了某个元数据的值,那查询条件就不对了;如果你用查阅项ID,那么因为背后那个隐藏列表有着随用随加的机制,如果你在设置视图的时候,某些值还从来没有使用过,当这些值被使用的时候,你的视图就查不到这些值了。而且不管你用哪一种方式,当管理员在后台更改了托管元数据的结构或者增加了新的节点的时候,这个视图条件都不再正确了。

一种变通的方式,是使用托管元数据导航,选中你需要的节点,然后把Url记下来,以后使用这个Url作为你这个视图的入口(SharePoint会在后台动态生成一个使用In运算符,包含所有子节点的CAML查询)。但是如果你要想在一个页面上放置多个视图,那就彻底没辙了。同样,对于“内容查询Web部件”来说,针对托管元数据的查询也会因为类似的原因而无能为力。

只能自己写代码做Web部件了(如果你有其他更好的方式,欢迎告诉我erucy9[_at_]gmail[_dot_]com)

3、API不正常的By Design行为

托管元数据提供了一套完整的API,这里面有一个方法需要特别说明,那就是GetTerms。

在TaxonomySession、TermStore、TermSet上都提供了这个方法,这个方法可以通过托管元数据的字符串值(Label)获取到特定名称的那一个(或多个)Term。

BUT……

当我们通过TaxonomySession和TermStore去使用这个方法的时候,只能获取到那些已经存在于TaxonomyHiddenList中的值(也就是网站中曾经使用过的值);只有当通过TermSet去使用GetTerms的时候,才能够获取到所有的值……

 

预告:

下一篇的内容是介绍托管元数据在SharePoint搜索结果页面中的“精简面板”(Refinement Panel)中的设置。

 
 

SharePoint Designer中无法显示任何列表

27 十二

最近在自己的虚机上发现了这样的现象:

SharePoint Designer 2010中,列表和库中间,无法显示任何内容,母版页之类的链接干脆就消失了,网站页面、网站资产这几个文档库也都显示“无法显示为文档库”:

spd

后来网上搜了一大圈,也琢磨了好久,想到刚刚卸载了一个工作流的产品,这是唯一一个可能造成影响的地方。

最终发现就是因为某个列表定义(List Definition)随着产品的卸载被干掉了,但是列表实例(List Instance)还在,这个也是feature卸载时候的一个问题。于是这些找不到对应定义的列表实例,导致了SPD出现这种状况。

解决方法也很简单,手动把那几个列表删掉就好了(如果是隐藏列表的话,需要用PowerShell或者自己写个Console删掉)。

 
 

文档库下载副本,文件名被截断

30

今天在TechNet上看到一个人问的问题(应该很早就有人发现这个问题了,2007应该就是这个样子),所以我估计我这个Blog里面写的也是很old的结论了。

原帖如下:sharepoint2010 从文档库下载文档副本 文件名被截断的问题

概括起来就是,当从文档库中下载副本的时候,过长的文件名被截断了(但是扩展名被保留);之前也有人发现过通过某些版本的浏览器文件另存为的时候也会这样。

这个原因是这样的:

下载副本是通过 /_layouts/download.aspx?SourceUrl=xxxx (xxxx就是你那个文件的路径)页面实现的,后台的类是Microsoft.SharePoint.ApplicationPages.Download,里面代码不多,不过篇幅所限就不全贴了,文件名是通过HttpHeader实现的,里面的核心方法AddContentDispostionHeader如下:

   1: private void AddContentDispositionHeader(string fileName)
   2: {
   3:     if ((this.Web != null) && (this.Web.Site.WebApplication.BrowserFileHandling == SPBrowserFileHandling.Strict))
   4:     {
   5:         base.Response.AppendHeader("X-Content-Type-Options", "nosniff");
   6:         base.Response.AppendHeader("X-Download-Options", "noopen");
   7:     }
   8:     base.Response.AppendHeader("Content-Disposition", "attachment;filename=\"" + SPHttpUtility.UrlEncodeFilenameForHttpHeader(fileName) + "\"");
   9: }
  10:  

可以看到,其中核心调用的方法是 SPHttpUtility.UrlEncodeFilenameForHttpHeader(str)

这个方法的实现如下:

   1: public static string UrlEncodeFilenameForHttpHeader(string fileName)
   2: {
   3:     string str = UrlEncodeForFilename(Path.GetExtension(fileName), 0x80, true);
   4:     string str2 = string.Empty;
   5:     if (str.Length < 0x80)
   6:     {
   7:         str2 = UrlEncodeForFilename(Path.GetFileNameWithoutExtension(fileName), 0x80 - str.Length, true);
   8:     }
   9:     return (str2 + str);
  10: }

我们可以看到,SharePoint把编码后文件名的总长度限制为128个字符,如果可能的话保留扩展名部分,截断超长的文件名。而Encode之后的中文类似于“%E4%B8%AD”这个样子(在UTF-8下,一个汉字用三个字节表示,前面那个表示“中”这个汉字),可以看到,一个汉字占了9个字符,因此就不难得到,如果扩展名是"“.docx”的话,那么前面的文件名长度最多只能容纳 (128 – 5) / 9 = 13.67,也就是13个汉字。

btw,实际上,在RFC中(参见:The Content-Disposition Header Field)中,规定了参数的长度不得超过78个字符,而且必须是编码的。当然,RFC只是个参考标准,每家都有自己的选择……

 
 

SharePoint 2010 SP1新功能(存储标准)

13

首先,“存储标准”名词翻译的真是太奇怪了……英文是“Storage Metrics”,功能就是观察网站、文档库、文件夹、文档所占用的存储空间。

这个功能在2007的时候其实就有,不过因为种种原因(比如性能之类的问题)在2010里面被去掉了,在SP1的时候,经过一番改进又加了回来。

功能在网站集管理中的“存储标准”,点击进入后,可以看到如下的界面:

image

点击网站的名字、文件夹的名字可以进入网站/文件夹,看到里面的内容,一直具体到某个文件所占用的空间(这个占用空间是该文件所有版本加在一起占用的空间,而不是最新版本的大小,所以可以真实反应实际的存储容量)。此外,界面中还能够看到这些对象在父容器中所占的百分比、在网站配额中所占的百分比(我这个网站集没有设置网站配额),以及最后修改时间。

需要注意的是,这些数据不是实时更新的(07里面是实时更新的,对性能有一定的影响),而是靠一个Timer Job定期更新的,这个Timer Job叫“存储标准处理”(这翻译……),默认是5分钟运行一次,可以根据情况自行修改:

image

 
 

SharePoint 2010 SP1的新功能(网站回收站)

13

SP1已经出了有两个月多了,估计有不少人都已经安装了,SP1里面新增的两个功能估计也有不少人知道了,不过可能还有些人不知道,所以还是写一写好了。

新功能之一就是网站/网站集回收站。

在SharePoint 2007的时候,推出了回收站功能,这是一个很多ITPro都非常需要的功能(尽管以国内的项目实施经验来看,最终用户能用到回收站的可能性很少,绝大部分时候都是开发者在用,汗……)。不过07的时候,回收站仅能针对网站中的文档库、列表、文件夹、文件和列表条目,如果网站被删掉了,甚至网站集被删掉了,就没有办法了(除非恢复数据库备份,或者借助一些第三方的备份/还原产品)。

到了2010 SP1的时候,产品组终于把网站/网站集的回收站功能加入了进来。

先来看网站(SPWeb)的回收站

当我们删除一个网站的时候,页面中会提示这个网站删除后将被发送到网站集回收站中,如下图所示:

image

删除之后,进入网站集回收站,在“已从最终用户回收站删除”这个部分,可以看到被删除的网站,并可以进行还原(说实话,我个人觉得放在这个位置有点奇怪,这里是放置那些被从网站回收站里删掉的东西的地方,也就是说是一个二级回收站),如下图:

image

接下来看看网站集(SPSite)的回收站

删除网站集可以使用删除顶级网站的方式,或者在管理中心里面直接删除网站集。不论采用任何一种方式都是同样的效果,而且在删除网站集的时候,页面上似乎并没有什么提示信息说这个删除是可以被还原的。

实际上,还原一个被删除的网站集是没有UI的,只能通过PowerShell来完成。

首先,可以使用Get-SPDeletedSite得到被删除的网站集:

image

然后,可以用Restore-SPDeletedSite的方式回复网站,利用PowerShell管道的方式传递:

image

 

参考博客:SharePoint 2010 SP1 – Site Recycle Bin

 
 

SharePoint上无法显示Lync的在线状态

15

今天伙同公司某Exchange MVP给某POC环境部署Lync,前面都比较顺利,结果到最后打开SharePoint发现无法查看用户的在线状态。

Google搜了个遍,连init.js的相关方法都打开看了一遍、ActiveX的文档也都看了一遍都木有找到原因。最后一个偶然的灵机一动,才发现居然忘了在AD里配置用户的邮箱(POC环境里不需要邮件演示)……

于是干脆把上网搜的内容总结一下,以后再出现此类问题的时候可以按照这个内容来进行排查。(其实SharePoint + Lync基本上不需要做任何配置就可以实现在线状态的查看的……)

0、Lync客户端一切正常(这个是前提条件,排除掉Lync服务器端配置的问题)

1、客户端是否安装了Lync客户端,是否正在运行(这个是废话,嗯)

2、客户端是否安装了Office(2010或者2007 + SP2或者2003 + SP2),因为在线状态的查看是依赖一个ActiveX控件(NameCtrl,文件是name.dll)来实现的,这个ActiveX控件是随着Office一起安装的。如果是Office 2007或者2003的话,需要安装到最新的一个SP。

3、是否使用的是IE7以上的浏览器(我看js代码,似乎对非IE也有一定程度的支持,不过我没试),是否启用了ActiveX(理由同上一条)

4、站点是否设置为Intranet或者受信任站点,这是那个ActiveX控件的要求(在NameCtrl的MSDN文档中写的)。不过Office365网站要家到信任站点的话,好像会出问题?这个有时间再试试……

5、是否在Web应用程序常规设置中开启了显示用户在线状态,默认是开启的(在管理中心 – 应用程序shezhi – Web应用程序设置 – 常规设置中)。另外多说一句,有很多网站,尤其是用SharePoint做的外网,我们在访问的时候经常会弹出那个NameCtrl的ActiveX提示询问我们是否启用,这个时候就可以通过这个设置,很简单的去掉这个提示信息。

6、用户在AD中是否配置了电子邮件?这又分成两个部分:

6.1、在个人网站里能否显示在线状态?如果不能的话,那应该是用户配置文件中的电子邮件没有配置(用户配置文件中也有一个SIP地址,我不能肯定是哪个起的作用)

6.2、在列表视图(或列表表单等地方)中,能否显示在线状态?如果不能的话,是因为网站的用户信息列表中没有配置电子邮件地址,即SPUser的Email属性(用户信息列表里面也有一个SIP地址,但是起作用的应该是电子邮件这个属性)。注意这个的数据来源和个人网站里面是不一样的,而且页面调用的代码也不太一样……

当然,如果用户配置文件和User Profile Service配置正常的话,是可以把用户属性从AD导入到用户配置文件,然后再进一步导入到网站的用户信息列表中的……如果不能的话,写个程序设置一下就好了……

 
 

组织结构配置文件的诡异行为

30

组织结构配置文件(OrganizationProfile),大家可能比较陌生,尤其对编程访问。具体的操作我就不在这里一一列举了,SDK里面也有例子,这里面只说一个可能和我们的预期不太一样的一个API行为。

在组织结构配置文件中,一个组织中的成员分为两种类型,Leader和Member。可以通过OrganizationProfile的AddMember方法来向这两个部分中加入用户(通过一个参数来进行区分是Leader还是Member),并通过RemoveMember的方式删除之。

如果这个用户不在Member中,我们可是使用下面这句话把用户user1加为Leader

   1: orgProfile.AddMember("domain\\user1", 
   2:               OrganizationMembershipType.Leader);

假设在之前这个组织中空无一人,执行完上面这句话的时候,user1既会出现在Leader中,也会出现在Member中,也就是说这个用户同时会自动加到Member里。这个行为很好理解,也make sense。

BUT!(又来了)

假设这个时候user1已经是Leader了(当然他也是Member),看下面这个代码:

   1: orgProfile.AddMember("domain\\user1",    
   2:               OrganizationMembershipType.Member);

执行完这句话你觉得会发生什么?把user1又一次加为Member,你觉得在上面那种假设情况下,应该不会发生任何变化是吧?错了!当我们执行完这句话的时候,user1还在Member中,但已经从Leader中消失掉了。很奇怪吧……我相信这是一个By Design的Bug……

换句话说,当我们要把一个用户加为成员的话,首先你得看一下这个用户是不是已经在成员中了,如果他已经存在,就不要再加一遍了。否则,万一这位用户是这个组织的领导,你一加,领导就没了(这在中国的项目中是多么可怕的行为)

 
 

UserProfile创建时拒绝访问?

30

这两天在做一个POC,组织结构的同步。做了一个通用框架,为了做示例和测试,写了一个到用户配置文件(UserProfile)和组织结构配置文件(OrganizationProfile)的接口,然后通过事件处理程序来调用UserProfile的相关接口,把信息同步到用户配置文件中。

然后就出现了问题:在通过事件处理程序调用UserProfileManager的CreateUserProfile方法时,SharePoint抛出了一个拒绝访问的异常:只有管理员和和本人才能创建用户配置文件云云……可是我执行的账号本来就是系统账号啊,我还又去User Profile Service那边查了一下,有完全控制的管理员权限啊……

然后经过一番搜索,发现关键问题的所在:

UserProfileManager在创建的时候,是依赖HttpContext(不是SPContext)的,而事件处理程序中是没有HttpContext的(即使在w3wp进程中运行也没有,SPContext也没有)。(但是为什么用Console程序写UserProfile程序的时候,也没有HttpContext,就能执行成功呢……不解)

临时岔开一下,而且由于是依赖HttpContext而不是SPContext,在提升权限的时候也会出一些问题,网上有人是重新构造了HttpContext作为创建SPServiceContext的参数,然后再去创建UserProfileManager。期间还用到了反射的方法修改WindowsIdentity的某个非公开属性……

上述方法太麻烦,于是我决定绕路,写一个Web Service扔到layouts里,这样就有HttpContext的上下文信息了。然后在事件处理程序中调用Web Service,并使用DefaultCredential(嗯,在我的场景中,只有管理员有权限去管理这个组织结构,所以直接传递当前身份,也不需要做权限提升)。看起来一切正常了……

BUT!人生最厉害的就是这个BUT!(好吧,这句话是九把刀说的)

当我去调用RemoveUserProfile,妄图去删除一个用户配置文件的时候,再次爆发了拒绝访问的异常(同样的代码Console还是正常,无语)。然后搜索了一下,发现msdn论坛上的一个帖子中描述了类似的问题,不过是在2007中的,本着试试看的方式按照如下方法尝试了一下(2007中的ServerContext被废弃,换成了SPServiceContext):

   1: SPSecurity.RunWithElevatedPriviliges(delegate(){
   2:   HttpContext oldCtx = HttpContext.Current;
   3:   SPServiceContext sc = SPServiceContext.GetContext(oldCtx);
   4:   HttpContext.Current = null;    // 亮点在这里
   5:   UserProfileManager upm = new UserProfileManager(sc);
   6:   upm.RemoveUserProfile("domain\\user");
   7:   HttpContext.Current = oldCtx;  // 还原回来
   8: });

于是乎就可耻的成功了……我表示很费解,也很无语……

 
 

SharePoint 2010 SP1更新发布

29

前几天微软SharePoint产品组正式发布了产品的SP1,中文版下载地址如下:

1、SharePoint Foundation 2010 Service Pack (KB2460058)

2、Microsoft SharePoint Foundation 2010 Language Pack Service Pack (KB2460059)(中文语言包)

3、Microsoft SharePoint Server 2010 Service Pack (KB2460045)

4、Server Language Pack 2010 Service Pack (KB2460056)(中文语言包)

5、Microsoft Office Web Apps 2010 Service Pack (KB2460073)

安装顺序也如上所示(如果你没有安装语言包的话,可以跳过2、4)。

[6月30日更新]如果你只安装了Foundation的话,只需要装1、2;如果你装的是Server,则不再需要安装Foundation的SP1,因为Server的SP是包含了FoundationSP的。(李劼的这篇Blog解释得很清楚:点我点我

此外,官方网站上也描述了一些安装的已知问题和注意事项(原文地址点我),主要包括:

  • 要确认有足够的剩余磁盘空间(几个SP的安装文件加一起有600来MB)
  • 安装SP1之后必须要重启计算机(当然重新运行配置向导是肯定要的,这个不用多说了)
  • 如果你只打算安装OWA的SP1,而SharePoint还保留在RTM(非SP1)版本的话,需要预先装两个补丁文件25106392510648,然后再安装OWA的SP1。
  • 在安装完SP1之后,新建的网站集的工作流Feature默认会禁用,需要手动启用一下(为啥会这样……)

 

此外,需要注意的是SP1包含了到2011年4月份为止的所有安装更新,但是不包括最新的6月份的安全更新(CU),所以微软建议在安装完SP1之后,再安装一下6月份的CU。不过一般来说,我们认为在生产环境中,除非确实遇到了问题,而且确认CU能够解决这个问题的话,再去安装,否则有一定的风险。

除了累积安全更新外,SP1还主要提供了如下更新内容:

  • 支持安装在SQL Server Denali上(下一版的SQL,目前还只有测试版)
  • 支持在移动网站集的时候使用浅拷贝(Shallow Copy,从文档来看,这个主要是针对应用了RBS的网站集,在迁移到另外一个内容数据库的时候,可以保留以前的RBS存储位置等设置)
  • 网站和网站集的回收站(这个功能终于出现了……现在你在删掉一个网站或网站集之后,可以很方便地从回收站里再还原回去了,就像以前还原列表或文档一样)
  • 增加了StorMan.aspx管理页面,可以查看到网站中文档库具体的存储大小,便于IT进行监控和管理
  • PPS中筛选器的改进
  • 增加对Chrome浏览器的支持