Meu receptor de recurso do SharePoint ativa um recurso de definição de lista, mas meu código não pode ver o modelo da lista até o "segundo passe"
-
22-09-2019 - |
Pergunta
Estou na minha sexta hora lutando com o que espero ter uma solução simples, então pensei em postar aqui.
Eu tenho um recurso com um receptor de recurso cujo único objetivo é ativar um recurso de definição de lista implantada e, em seguida, criar uma instância dessa nova definição de lista.
O recurso de definição da lista, chamado "Lista de Acesso Custom", está escopo na Web.
Portanto, meu receptor de recurso ativa esse recurso de definição de lista, tendo GUID "1E503BDA-803B-4A1A-A042-019FA1A70C":
...
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
}
Esse código é executado bem, e o recurso de definição da lista é ativado e a nova definição da lista aparece na opção de menu "Criar" no UI.
No entanto, é aqui que meu problema começa. A próxima linha do meu código de receptor de recursos tenta criar uma instância desta lista recém-disponível:
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);
Mas a linha SplistTemplate listTemplate = web.listtemplates ["Lista de acesso personalizado"]; Jogos uma exceção com "O valor não se enquadra no intervalo esperado". - O modelo de lista, apesar de ter sido implantado, visível e disponível na interface do usuário da ação do menu "Criar", não pode ser encontrado no código do receptor.
Debugando o código confirma que o Web.ListTemplates SplistTemplateCollection Não contém uma entrada para esta nova "lista de acesso personalizada", apesar da interface do usuário sugerir o contrário.
E aqui está a coisa estranha. Uma exceção é lançada, mas se eu executar novamente o código, ou seja, reativar o recurso na interface do usuário, para reexecionar esse receptor, o modelo de lista é então encontrado -
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
Portanto, em poucas palavras - inicialmente, após ativar um recurso que, através do código do receptor, ativa um recurso de definição de lista, essa definição de lista é não Visível até depois de um "postback" ou alguma forma de "atualização do spweb". Então é visível.
Estou perdendo alguma coisa aqui? Uma chamada de web.update () aqui:
try
{
SPFeatureCollection featureCollection = web.Features;
featureCollection.Add(new Guid(featureGUID), true); // true to force activation
web.Update();
}
...
faz nada. Existe alguma maneira de "atualizar" o objeto SPWeb para que o novo modelo de lista possa ser visto e usado?
A solução alternativa que encontrei, por enquanto, é adicionar o recurso de modelo de lista "Lista de acesso personalizado" como uma dependência de ativação no próprio recurso "Parent" do recurso de recurso e para tornar o recurso de modelo de lista "Lista de acesso personalizado" oculto. Dessa forma, até onde eu sei, o recurso de definição de lista personalizado é ativado à força e eu acho que isso web.ListTemplates ["Lista de acesso personalizado"]; seja encontrado.
Mas prefiro muito o trabalho de abordagem anterior - a ativar, no meu código de receptor, o recurso de definição da lista e, em seguida, encontrá -lo para que uma instância da lista possa ser criada.
Solução
Andrew,
O problema é ver com eventos assíncronos internos e o momento da atividade. Como você diz, se você for embora e voltar, ele funciona - ou seja, o evento assíncrono foi concluído. Você está tratando o featureCollection.add como um método Synchronus.
O que você realmente deveria estar fazendo se precisar de um modelo e uma instância da lista criada ao mesmo tempo é usar a estrutura XML para isso.
Adicione A ao seu recurso que possui o modelo de lista ou, alternativamente, adicione um novo recurso para a instância da lista e faça referência ao recurso do modelo de lista.
Andrew
Outras dicas
Você precisa ligar para o EnsureListsData na SplistCollection que você acabou de atualizar.
http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.splistcollection.ensurelistsdata.aspx
Parece que o modelo de lista ainda não foi criado. Você pode tentar fazer um loop e esperar para ser criado
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();
}
}
}