Domanda

Voglio eliminare alcuni dei webparts dai miei siti quando vengono create. Ho pinzato una funzione che esegue il codice personalizzato. Ho attaccato le basi di ciò che fa seguito, edito per brevità.

Funziona, ma quando si crea un mio sito si ottiene il messaggio di errore "L'operazione non può essere completata perché il web part è stata eliminata da un altro utente o non è valido.", Direi, perché sta cercando di caricare i webparts che il thread in background è a metà strada attraverso la cancellazione. Aggiorna e la pagina viene caricata bene.

Tutte le idee su come ottenere intorno a questo?

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    thread.Start(deletethestuff)        
}

public override void DeleteTheStuff
{
    while (checksiteisprovisioned == false) Thread.Sleep(1000);

    SPFile page = web.RootFolder.Files["default.aspx"];
    SPLimitedWebPartManager manager = page.GetLimitedWebPartManager(PersonalizationScope.Shared));
    foreach (Microsoft.SharePoint.WebPartPages.WebPart webPart in webParts)
    {
        if (webPart.Title == "onetodelete")
        {
            manager.DeleteWebPart(webPart);
        }
    }
    page.Update();
}
È stato utile?

Soluzione

Il modo in cui faccio questo è come descritto nel post sul blog di Steve Peschka sul blog del team di SharePoint: http://blogs.msdn.com/sharepoint/archive/2007/03/22/customizing-moss-2007-my-sites -Entro-la-enterprise.aspx

Altri suggerimenti

Il problema qui è che si sta modificando la raccolta web part, allo stesso tempo, come l'iterazione attraverso di essa. È necessario costruire una raccolta differenziata e quindi utilizzare tale per la cancellazione per esempio:.

SPFile page = web.RootFolder.Files["default.aspx"];
SPLimitedWebPartManager wpmShared = page.GetLimitedWebPartManager(PersonalizationScope.Shared);

List<WebPart> partsToProcess = new List<WebPart>();

foreach (WebPart part in wpmShared.WebParts)
{
     if (part.Title == "onetodelete")
     {
         partsToProcess.Add(part);
     }
}

foreach (WebPart webPart in partsToProcess)
{
     wpmShared.DeleteWebPart(webPart);
}     

page.Update();

Il modo in cui ho sempre fatto è quello di creare un altro elemento che potrebbe eliminare i webparts ma non fiocco al altri siti. Poi avrei un'altra caratteristica che è cucito con punti metallici ai siti che potrebbero dare il via due cose:

Uno, ho usato le discussioni e funziona abbastanza bene ma l'ho fatto un po 'diverso da quello che:

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    using (SPWeb web = (SPWeb)properties.Feature.Parent)
    {
        if (web == null) throw new ApplicationException("Web could not be found");

        ThreadPool.QueueUserWorkItem(new WaitCallback(RunProcess), web.Url);
    }
}

private void RunProcess(object state)
{
    bool provisioned = false;
    SPWeb web = null;

    try
    {
        for (int i = 0; i < 100 && provisioned == false; i++)
        {
            try
            {
                string url = (string)state;
                using (SPSite site = new SPSite(url))
                {
                    web = site.OpenWeb();
                    if (web.Provisioned)
                    {
                        provisioned = true;
                        break;
                    }

                    if (web != null)
                    {
                        web.Dispose();
                    }

                    Thread.Sleep(3000);
                }
            }
            catch { }
            finally
            {
                if (web != null &&
                    provisioned == false)
                {
                    web.Dispose();
                }
            }
        }

        if (provisioned)
        {
            DoSomething(web);
        }
        else
        {
            throw new ApplicationException("Web site never provisioned");
        }
    }
    finally
    {
        if (web != null)
        {
            web.Dispose();
        }
    }
}

e poi nel fare qualcosa che mi sarebbe attivare la funzione senza pinzatura.

Due. Vorrei aggiungere un processo timer impostato una sola volta per l'esecuzione in 5 minuti, che sarebbe anche attivare la stessa caratteristica.

In questo modo il 99% delle volte il filo sarebbe eseguire correttamente, ma l'1% che non lo fa, v'è un processo timer che si prenderà cura di esso dopo un po 'di ritardo.

Non vorrei mai andare con un thread in background come questo durante il sito provisioning, si è appena fatto a fallire.

Nel tuo caso mi piacerebbe creare una copia della definizione MSITE del sito, senza le parti Web e utilizzare quel sito def per i siti personali, invece.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a sharepoint.stackexchange
scroll top