Pregunta

Quiero eliminar algunos de los webparts de mis sitios cuando se crean. He engrapé una característica que se ejecuta el código personalizado. Me he adjuntado los fundamentos de lo que lo hace a continuación, editado por razones de brevedad.

Funciona, pero cuando se crea un sitio de mi se obtiene el mensaje de error "La operación no pudo completarse porque el elemento Web se ha eliminado por otro usuario o no es válido.", Supongo que porque está tratando de cargar los webparts que el subproceso de fondo está a medio camino a través de la eliminación. Actualizar y la multa carga la página.

Alguna idea de cómo evitar esto?

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();
}
¿Fue útil?

Solución

La forma en que hago esto es como se describe en el blog de Steve Peschka en el blog del equipo de SharePoint: http://blogs.msdn.com/sharepoint/archive/2007/03/22/customizing-moss-2007-my-sites -dentro-la-enterprise.aspx

Otros consejos

El problema aquí es que está modificando la colección de piezas de la tela al mismo tiempo que la iteración a través de él. Es necesario construir una colección separada y luego utilizarlo para la eliminación por ejemplo:.

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();

La forma en que siempre he hecho es crear otra característica que elimine los webparts pero no de primera necesidad a ningún sitio. Entonces tendría otra característica que se grapa a los sitios que se inicio a dos cosas:

Uno de ellos, que utiliza hilos y funciona bastante bien, pero lo hice un poco diferente de lo que:

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

y luego en algo hacer yo activaría la función sin grapar.

Dos. Yo añadiría una hora establecida trabajo del temporizador para funcionar en 5 minutos, que también activarían la misma característica.

De esta manera el 99% de las veces el hilo ejecutaría correctamente, pero el 1% que es no es así, hay un trabajo del temporizador que se hará cargo de ella después de un poco de retraso.

Yo nunca iría con un subproceso de fondo como éste durante el sitio de aprovisionamiento, que se acaba de hacer fracasar.

En el caso de que crearía una copia de la definición MSITE Sitio, sin los elementos web y utilizar ese sitio def de los Mis sitios en su lugar.

Licenciado bajo: CC-BY-SA con atribución
scroll top