In the current project we're doing, we create multiple document libraries in a site when a user selects a value from a list. The choices for the list are business templates for new Contracts. A Contract can be implemented through several document libraries. Each document library makes up part of a full document that is assembled together later when the user wants to preview the whole thing. Okay, so we're golden. When we first did this we thought this would work. Iterate through all the custom list templates and build a new document library based on it. This code does that, but doesn't work:
public void DoesNotWork()
{
SPSite siteCollection = new SPSite("http://localhost/sites/sitename");
SPWeb web = siteCollection.OpenWeb();
SPListTemplateCollection customListTemplates = siteCollection.GetCustomListTemplates(web);
SPSite testSite = new SPSite("http://localhost/sites/sitename/subsite");
SPWeb testWeb = testSite.OpenWeb();
foreach (SPListTemplate spListTemplate in customListTemplates)
{
string newListTitle = spListTemplate.Name;
// this fails with internal error when adding multiple lists
testWeb.Lists.Add(newListTitle, "", spListTemplate);
// this doesn't fix it
testWeb.Update();
}
}
The problem was that we would open the target web (testWeb in the above code) and create all the document libraries we needed to based on the templates from the parent site. These were adding new document libraries based on a template, everything was valid but it would throw an exception on the second call to testWeb.Lists.Add. Even with the testWeb.Update call it still didn't help. So we had to collapse all our documents into a single one until we figured out why.
After doing a couple of spike projects we found that we had to open the web each time for the multicreate to work. So this code fixed it:
public void Works()
{
SPSite siteCollection = new SPSite("http://localhost/sites/sitename");
SPWeb web = siteCollection.OpenWeb();
SPListTemplateCollection customListTemplates = siteCollection.GetCustomListTemplates(web);
foreach (SPListTemplate spListTemplate in customListTemplates)
{
SPSite testSite = new SPSite("http://localhost/sites/sitename/subsite");
SPWeb testWeb = testSite.OpenWeb();
string newListTitle = spListTemplate.Name;
testWeb.Lists.Add(newListTitle, "", spListTemplate);
}
}
Yes, you should call Dispose on the SPSite and SPWeb objects. In any case, this code works but I'm still not sure why?