[MOSS 2007] WebParts del tipo ErrorWebPart aparecen cuando usamos SPLimitedWebPartManager

El otro día desarrollando una feature para conectar webparts programáticamente (Escribiré algo sobre esto muy pronto) me encontré un pequeño problema a la hora de listar los webparts de un sitio usando la clase SPLimitedWebPartManager y era que los webparts de tipo ContentByQueryWebPart y los SummaryLink me los devolvía del tipo ErrorWebPart.

Esto se produce cuando ejecutamos el código en la feature receivers o en una aplicación cliente fuera de MOSS, porque probé el código en un webpart y funcionó. Esto me llevo a pensar que algo había que me estaba faltando y claro está que no disponemos en la feature y ni en la aplicación cliente del SPContext, al cual se accede desde dichos webparts para crear las url relativas de las tres hojas de estilo Xsl (MainStyle, HeaderStyle or ItemStyle).

Googleando encontré la solución a dicho problema que es crear un contexto falso:

if (HttpContext.Current == null)

{

    HttpRequest httpRequest = new HttpRequest(String.Empty, web.Url, String.Empty);

    HttpContext.Current = new HttpContext(httpRequest, new HttpResponse(new StringWriter()));

    HttpContext.Current.Items["HttpHandlerSPWeb"] = web;

}

Sí os preguntáis como yo me pregunté por qué en el contexto mete el item HttpHandlerSPWeb, es por qué la clase SPContext en su propiedad estática Current, si vemos el código con reflector hace uso del método GetContextWeb de la clase SPControl:

public static SPContext Current

{

    get

    {

        SPContext context = null;

        if (HttpContext.Current == null)

        {

            return context;

        }

        while (SPControl.GetContextWeb(HttpContext.Current) != null)

        {

            try

            {

                context = GetContext(HttpContext.Current);

            }

            catch (FileNotFoundException)

            {

            }

            return context;

        }

        return null;

    }

}

Y sí miramos el código de SPControl.GetContextWeb():

public static SPWeb GetContextWeb(HttpContext context)

{

    return SPWebEnsureSPControl(context);

}

private static SPWeb SPWebEnsureSPControl(HttpContext context)

{

    SPWeb web = (SPWeb) context.Items["HttpHandlerSPWeb"];

    if (web == null)

    {

        if (context.User == null)

        {

            throw new InvalidOperationException();

        }

        if (SPSecurity.ImpersonatingSelf || (SPSecurity.UserToken != null))

        {

            throw new InvalidOperationException();

        }

        try

        {

            SPSite site;

            context.Items["HttpHandlerSPSite"] = site = new SPSite(SPFarm.Local, SPAlternateUrl.ContextUri, true);

            web = site.OpenWeb();

            context.Items["HttpHandlerSPWeb"] = web;

            SPRequestModule.InitContextWeb(context, web);

            if (!SPContext.GetShouldInitThreadCultureWhenContextWebIsInited(context))

            {

                return web;

            }

            web.SetThreadCultureAfterInit();

        }

        catch (FileNotFoundException)

        {

        }

    }

    return web;

}

 

Ahí podemos ver como sí no tenemos un contexto web y no tenemos el item HttpHandlerSPWeb obtendremos siempre este dichoso error.

Al final lo suyo es que liberemos el contexto:

HttpContext.Current = null;

 

Espero que os sirva, salu2!!!

2 comentarios en “[MOSS 2007] WebParts del tipo ErrorWebPart aparecen cuando usamos SPLimitedWebPartManager”

  1. Gracias Luís, has salvado todas nuestras vidas ;). En serio, fue genial para lo que comentas, y para otras muchas cosas. Muy útil también en feature receivers, que lo sepas… 😉

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *