Marco Rizzi SPBlog

SharePoint, web and so many things.

Bug nel valore restituito da SPWeb.Configuration nei subweb di un site se acceduti via SPWeb.Webs

Versioni SharePoint testate: 
- SharePoint 2007 con SP2 + varie update
- SharePoint 2010 beta. 

Segnalo un bug che mi ha tenuto impegnato negli ultimi giorni. Navigando via object model sui subweb di una sito tramite SPWeb.Webs, la proprietà SPWeb.Configuration restituisce correttamente il configuration ID del template utilizzato sul rootweb, mentre per tutti gli altri –1.

Ecco il codice di una console application per riprodurre il comportamento:

static void Main(string[] args)

{

    using (SPSite site = new SPSite(args[0]))

    {

        InspectWeb(site.RootWeb, true);

    }

}

static void InspectWeb(Microsoft.SharePoint.SPWeb web, bool bRecurse)

{

    Console.WriteLine("web.ID: " + web.ID);

    Console.WriteLine(" web.Configuration: " + web.Configuration);

    if (bRecurse)

    {

        foreach (Microsoft.SharePoint.SPWeb subweb in web.Webs)

        {

            try

            {

                InspectWeb(subweb, bRecurse);

            }

            finally

            {

                subweb.Dispose();

            }

        }

    }

}

Mentre se prima di leggere la proprietà Configuration leggo un'altra delle proprietà del web ad esempio SPWeb.WebTemplateID non si presenta più l'anomalia, SPWeb.Configuration restituisce il valore corretto.

Console.WriteLine("web.ID: " + web.ID);

Console.WriteLine(" web.WebTemplateId: " + web.WebTemplateId);

Console.WriteLine(" web.Configuration: " + web.Configuration);

Facendo un rapido approfondimento con Refector trovo che SPWeb.Configuration va ad inizializzare il web chiamando il metodo InitWeb solo se la variabile m_nProvisionConfig, di tipo Nullable<Int16>, ha un valore.

public short Configuration

{

    get

    {

        if (!this.m_nProvisionConfig.HasValue)

        {

            this.InitWeb();

        }

        return this.m_nProvisionConfig.Value;

    }

}

Indagando scopro che la variabile viene inzializzata con valore di default –1 quando si accedere a SPWeb.Webs e ciò naturalmente non permette di eseguire il metodo InitWeb() nella get della proprietà Configuration.
Questo invece è il codice di SPWeb.Title che l'inizializza correttamente l'oggetto Web

public string Title

{

    get

    {

        if (this.m_strTitle == null)

        {

            this.InitWeb();

        }

        return this.m_strTitle;

    }

}

Per tornare al discorso delle inizializzazioni con valori di default si può notare che la get del SPWeb.WebTemplateId esegue correttamente il test per decidere se eseguire o meno il metodo InitWeb escludendo correttamente il valore settato dal metodo SPWeb.Webs

public int WebTemplateId

{

    get

    {

        if (this.m_nWebTemplateId == -1)

        {

            this.InitWeb();

        }

        return this.m_nWebTemplateId;

    }

}

I workround sono:

  • leggere i subweb usando il metodo GetSubwebsForCurrentUser. Questo è il link per il dettaglio su MSDN.
  • leggere una property del web che inizializza correttamente l'oggetto prima di accedere a quella Configuration. Attenzione: non tutte le get delle property del SPWeb hanno le logiche sopra descritte per inizializzare l'oggetto (esempio ID e Url non lo fanno)

   

Technorati Tags: sharepoint,development,page layouts,bug