2007年4月20日,星期五

在Codeplex上创建查找字段的功能

在一个 最近贴文 我为功能接收器发布了一些示例代码,该功能接收器将创建查找字段(从列表中获取其数据的站点列)。几个人发表评论,要求提供完整的文件。

我把它们放在Codeplex上 http://www.codeplex.com/SP2007LookupFields.

一些注意事项:-

  • 我已经增强了解决方案的通用性,并且可以在一个功能中创建多个查找字段。现在,列表的名称可以包含在CAML中,功能接收器将对此进行解析,查找列表并使用API​​通过列表GUID修复引用。请注意,当前列表必须位于根网站中,尽管扩展该列表很简单。
  • 所有硬编码值均已删除,例如包含CAML定义的文件的路径现在作为功能属性传递。
  • 我在之前的文章中提到过,您可能具有从属功能,以便包含功能接收器的程序集也可以在激活功能时自动部署。因为程序集只能使用SharePoint进行部署,所以这不太有意义。 解决方案 特征。 因此,我将功能包装在部署程序集和功能的SharePoint解决方案中。激活功能后,程序集已经在GAC中,并且功能接收器运行良好。请注意,增强解决方案也很简单,以便使用适用于高度受控环境的CAS策略将程序集部署到站点容器中。
  • 我还包括一个STSADM脚本,用于部署解决方案-您需要编辑此文件中的URL以指向您的SharePoint网站。

希望这是有用的,如果您有反馈意见,请告诉我。

21条评论:

匿名 said...

克里斯,你好
很好。这实际上有效。但是我还有一个问题要问您。创建站点定义的新实例时,如何实现从头开始的功能接收器? Visual Studio提供了类似Site Provisioning处理程序类SiteProvisioning.cs的内容-但我知道它实际上不起作用。你对此一无所知吗?
提前THX

克里斯·奥'Brien 说过...

你好

是的,因此假设您要使用VSeWSS随附的模板之一创建VS项目,则解决方案中将存在一个名为SiteProvisioning.cs的文件。

我对此没有任何特别的问题-我可以编写代码来修改站点,而没有任何问题。我可能会写更多细节的文章,因为这是一个有很多可能性的领域。

你有什么问题?

克里斯。

匿名 said...

嘿克里斯

打算提早发表评论,感谢您对此项目的支持。我下载了它,并在不做任何调整的情况下,使其在数小时内启动并运行。我真正喜欢的是您采用的通用方法,这意味着要定位的特定站点列的详细信息都保存在配置文件中-当场!它就像一种魅力,“感觉”就像管理此重要配置步骤的正确方法。

好一个。

克里斯·奥'Brien 说过...

感谢您对Matt的反馈,非常感谢!

克里斯。

布鲁斯·桑德曼(Bruce Sandeman) 说过...

克里斯,你好
非常有用的代码,但是由于某些原因,我只能使它适用于在xml文件字段中定义的第一列。

我可以很高兴地更改第一个字段的名称,并以不同的方式创建它,但是其中有多个字段似乎不起作用。
你能给我指点吗?
谢谢
布鲁斯

布鲁斯·桑德曼(Bruce Sandeman) 说过...

别担心,
I found the problem, needs a line of code replaced as 在 http://www.codeplex.com/SP2007LookupFields/WorkItem/View.aspx?WorkItemId=5485

克里斯·奥'Brien 说过...

嗨布鲁斯,

英镑的工作,非常感谢您的贡献。

我已经更新了源代码,并通过更新签入了新版本。

非常感激..

克里斯。

杰西卡·哈迪(Jessica Hardy) 说过...

克里斯,

我已经使用此博客条目来获取我根据查找列表创建网站列所需的内容。谢谢您的帮助!现在,我必须跨越的下一个桥梁是将它们集成到列表定义中。我可以将查找列表站点列转换为内容类型,因为它使用FieldRef,但是在创建列表定义时,即使它们属于内容类型,您基本上也必须重新定义每个字段(顺便说一句,我觉得很烦人:)) 。有任何想法吗?

谢谢,
杰西卡(Jessica)

克里斯·奥'Brien 说过...

嗨,杰西卡,

嗯,恐怕我还没有考虑将列添加到列表定义中。但是我以为您需要将FieldRef条目添加到列表的schema.xml文件中。我注意到这里有一个“字段”元素,所以可能就是这个地方。

HTH,

克里斯。

约翰·海格 说过...

克里斯,你好

我认为这篇文章很棒。

我有一个通过VSeWSS创建的网站定义解决方案,它具有两种内容类型(即“联系人”和“地址”),
然后是根据这些内容类型创建的两个列表“ ContactList”和“ AddressList”。
第二内容类型“地址”具有引用联系人列表的查找字段“ RelatedContact”。

是否可以将您在此处编写的功能接收器解决方案(在Codeplex上)添加到我的“站点定义解决方案”中,特别是添加到
SiteProvisioning.cs(如上所述通过SiteProvisioning.cs完成),以便在配置站点时
查找字段具有正确的GUID,该GUID引用了在配置站点时WSS创建的ContactList的GUID?

谢谢,

约翰·海格

克里斯·奥'Brien 说过...

嗨,约翰,

绝对-我想不出什么都不行的原因。可能有两种方法:

-切掉我使用的代码并将其添加到您的SiteProvisioning.cs中(如您所建议)
- 采用 装订功能 将代码链接到网站定义

两者都应该做。让我知道你是怎么办的。

干杯,

克里斯。

约翰·海格 说过...

这是个好消息。我将告诉您它的进展情况,一旦成功,我将把我的代码发送过来,希望可以将其发布,以便其他人可以从中受益。

谢谢,

约翰

约翰·海格 说过...

克里斯,你好

我切掉了您编写并添加到SiteProvisioning.cs中的代码,更新了将替换GUID的XML文件中的查找字段,通过VSeWSS进行了部署,然后创建了一个站点,并且在创建站点时出现此错误“值不落在预期范围内。”我进行了一次Google搜索,发现问题可能出在XML内,然后再次检查了XML。

阅读您的文章后的另一个担心是,我的感觉是我无法通过VSeWSS做到这一点,因此需要像本文中一样(代码复合体等)使用功能/功能接收器创建一个独立的解决方案,然后移动所有内容如您的文章“在新网站上自动设置自定义权限”或“创建,部署和更新自定义网站定义”中所述,将类型,列表等添加到VS解决方案中

是这样吗

谢谢,

约翰

约翰·海格 说过...

克里斯,你好

我可以在siteprovision.cs中找到解决方法。

这是用于创建查找字段的代码:

在OnActivated内部,我添加了以下代码:

SPWeb网站;
SPSite网站;

如果(properties.Feature.Parent是SPWeb)
{
web = properties.Feature.Parent作为SPWeb;
site = web.Site;
}
其他
{
site = properties.Feature.Parent作为SPSite;
web = site.RootWeb;
}

web.AllowUnsafeUpdates = true;

SPList addressList = web.Lists [“ AddressCTList”];
SPList provinceList = web.Lists [“ ProvinceCTList”];

provinceList.Fields.AddLookup(“ RelAddress”,addressList.ID,true);
provinceList.Update();

谢谢,

约翰

克里斯·奥'Brien 说过...

嗨,约翰,

很高兴听到您得到排序。感谢您发布代码!

干杯,

克里斯。

附言作为对您先前评论的回应,如果您沿Feature路线行驶,将无法为此使用VSeWSS。这是因为VSeWSS不支持功能接收器,而是在每次构建时都重新生成文件。

然而 ,有可能 VSeWSS 1.1 CTP ,因为这使开发人员可以手动将其添加到功能文件中。请注意,尽管这仍处于“预览发布”阶段,所以可能存在奇怪的错误。

HTH,

克里斯。

匿名 said...

嗨,很好的解释。但是,我有一个问题。当代码尝试删除该列时,出现错误,提示它仍与列表或内容类型相关联。

查看该站点,那里没有其他列表,所以这不是问题。但是,在实际上调用删除代码的FeatureActivated事件中,似乎已经部署了包含此查找站点列的内容类型(我可以在调试器的断点中使用对象模型找到它),我想这就是原因删除将无法进行。您知道我为什么要这样做吗?

谢谢,
阿德里安

克里斯·奥'Brien 说过...

嗨,艾德里安,

我认为这是预期的行为。

除了从任何列表中删除该字段之外,还需要从任何内容类型中删除它(或删除内容类型),然后才能删除该字段。

如果您还从内容类型中删除,则应该可以。

HTH,

克里斯。

博斯托里 说过...

克里斯 -

我要查找列的问题是这个。为什么不能将任务列表中的“分配给列”用作查找列。

我有一个与文档库关联的工作流程,我希望将工作流程分配给谁作为我的文档库中的一列。

此功能可以执行类似的操作吗?那可能吗?

布赖恩·比尔布罗 说过...

克里斯,你好
感谢您的博客文章。这些很棒。我的团队刚刚进入SharePoint,这些资源非常有用。

我只是想传递一些信息。我正在做与上述约翰·海格完全相同的事情。但是,我略有变化。我不会动态添加查找列。我通过CAML定义文件正常添加。

我要做的只是使用正确的列表引用更新现有字段。我有点喜欢这种方法,因为其他所有内容都可以定义为普通方法。

这是我的零钱:

SPList applicationsList = web.Lists [“ MercerApplicationsListDefinition instance”];

SPList projectsList = web.Lists [“ MercerProjectsListDefinition instance”];

projectsList.Fields [“ Applications”]。SchemaXml = projectsList.Fields [“ Applications”]。SchemaXml.Replace(“ fd648b7f-9e58-469e-b1cf-5d365e26764c”,applicationsList.ID.ToString());

projectsList.Update();

克里斯·奥'Brien 说过...

@ben,

抱歉,没有答案。如果此列属于“人员/组”类型,并且此列类型不能用作查找,则可能是它不受支持。

抱歉,我帮不上忙,

克里斯。

克里斯·奥'Brien 说过...

@Brian Bilbro,

这是一个很好的提示-从逻辑上考虑那里发生的事情,我不应该感到惊讶。我猜这两种方式都需要运行一些代码,因此可能在哪里/什么是优先选择的问题。

虽然总的来说,SchemaXml属性是可写的并且可以用于模式更新,这一事实带来了很多可能性:-)

干杯,

克里斯。