我正在进入第六个小时与希望应该有一个简单解决方案的斗争,所以我想我会在这里发布。
我有一个功能接收器的功能,其唯一目的是激活部署列表定义功能,然后创建该新列表定义的实例。
列表定义功能称为“自定义访问列表”,其范围限于Web。
所以我的功能接收器激活了这个列表定义功能,GUID为“1E503BDA-803B-4a1a-A042-019FA1A70C4C”:
...
string featureGuid = "1E503BDA-803B-4a1a-A042-019FA1A70C4C"; // my 'Custom try
{
SPFeatureCollection featureCollection = web.Features;
featureCollection.Add(new Guid(featureGUID), true); // activat the 'Custom Access List' feature
}
catch (Exception e)
{
// log exception
}
此代码执行正常,列表定义功能已激活,新列表定义显示在UI中的“创建”站点菜单选项中。
然而,这是我的问题开始的地方。然后,我的功能接收器代码的下一行尝试创建这个新可用列表的实例:
SPListTemplate listTemplate = web.ListTemplates["Custom Access List"]; // exception! Value does not fall within the expected range
web.Lists.Add("My new custom access list","", listTemplate);
但行 SPListTemplate listTemplate = web.ListTemplates [“Custom Access List”]; 会抛出一个异常,其中“Value不在预期范围内”。 - 列表模板尽管在“创建”站点菜单操作下在UI中部署,可见和可用,但在接收器代码中找不到。
调试代码确认 web.ListTemplates SPListTemplateCollection 不包含此新“自定义访问列表”的条目,尽管UI建议不这样做。
这是奇怪的事情。抛出异常,但如果我重新运行代码,即重新激活UI中的功能,重新执行该功能接收器,则会找到列表模板 -
SPListTemplate listTemplate = web.ListTemplates["Custom Access List"]; // found this time. It sees it the second time around
web.Lists.Add("My new custom access list","", listTemplate); // works fine
因此,简而言之 - 最初,在激活一个功能后,通过接收器代码激活列表定义功能,该列表定义不可见,直到“回发”或某种形式的“SPWeb刷新”。 然后它是可见的。
我在这里遗漏了什么吗?在这里调用web.Update():
try
{
SPFeatureCollection featureCollection = web.Features;
featureCollection.Add(new Guid(featureGUID), true); // true to force activation
web.Update();
}
...
什么都不做。有什么方法可以“刷新”SPWeb对象,以便可以看到和使用新的列表模板吗?
我现在发现的解决方法是在“父”功能接收器本身中添加“自定义访问列表”列表模板功能作为激活依赖项,并使“自定义访问列表”列表模板功能隐藏。这样,据我所知,自定义列表定义功能被强制激活,我发现 web.ListTemplates [“自定义访问列表”]; 被找到。
但我更倾向于前一种方法 - 在我的接收器代码中激活列表定义功能,然后找到它,以便可以创建列表的实例。
答案 0 :(得分:1)
安德鲁,
问题在于内部异步事件和活动的时间。如你所说,如果你离开并回来它是有效的 - 即异步事件已经完成。您正在将featureCollection.Add视为同步方法。
如果您需要一个模板并同时创建一个列表实例,那么您真正应该做的是使用XML框架。
添加到包含列表模板的功能,或者为列表实例添加新功能并引用列表模板的FeatureID。
安德鲁
答案 1 :(得分:0)
您需要在刚刚更新的SPListCollection上调用EnsureListsData。
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistcollection.ensurelistsdata.aspx
答案 2 :(得分:-1)
似乎尚未创建列表模板。您可以尝试循环并等待创建
using(SPWeb web = site.OpenWeb())
{
SPListTemplate listTemplate = null;
while (listTemplate == null)
{
Thread.Sleep(1000);
try
{
listTemplate = web.ListTemplates["Custom Access List"];
if (listTemplate != null)
{
// here your code
web.Lists.Add("My new custom access list", "", listTemplate);
}
}
catch
{
web = site.OpenWeb();
}
}
}