[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!!!

Published 18/11/2009 11:18 por Luis Ruiz Pavón
Comparte este post:
http://geeks.ms/blogs/lruiz/archive/2009/11/18/moss-2007-webparts-del-tipo-errorwebpart-aparecen-cuando-usamos-splimitedwebpartmanager.aspx

Comentarios

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

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

Thursday, November 19, 2009 3:22 PM por David Martos

# [MOSS 2007] Conectar WebParts programáticamente

Conectar 2 WebParts (por ejemplo un buscador y grid) a través del interfaz de SharePoint es una

Tuesday, January 19, 2010 8:53 AM por Amigo mío Siempre estas Programando en .NET