我的SharePoint功能接收器激活列表定义功能,但我的代码在“第二次传递”之前无法看到列表模板

时间:2010-01-21 19:51:12

标签: c# sharepoint list-definition list-template

我正在进入第六个小时与希望应该有一个简单解决方案的斗争,所以我想我会在这里发布。

我有一个功能接收器的功能,其唯一目的是激活部署列表定义功能,然后创建该新列表定义的实例。

列表定义功能称为“自定义访问列表”,其范围限于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 [“自定义访问列表”]; 被找到。

但我更倾向于前一种方法 - 在我的接收器代码中激活列表定义功能,然后找到它,以便可以创建列表的实例。

3 个答案:

答案 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();
                }
            }
        }