25 listopada 2011

Dwie instancje webpart'ów oraz IsClosed

Tańcowały dwa webpart'y


Praca z webpart'ami od strony SharePoint API może być czasami frustrująca. Kilkukrotnie zdarzyło mi się exportować konfigurację, usuwać instancję, zmieniać właściwości webpartów. Przynajmniej trzy razy byłem zaskoczony tym, że strona wyświetla np. jednego webpart'a a kolekcja Webparts z obiektu SPLimitedWebPartManager zwraca więcej instancji, często tego samego typu.

Pewnie domyślacie się, że te dodatkowe instancje webpart'ów to zamknięte, a nie usunięte webparty'y. Rezydują sobie one szczęśliwe w kontentowej bazie danych, aczkolwiek nie są wyświetlane w UI.

Wszystko byłoby wporządku, gdybym już trzeci raz o tym nie zapomniał, że jeżeli modyfikuje widoczne webpart'y, to muszę wziąć pod uwagę też te niewidoczne instancje.

Moim zadaniem było usunięcie duplikatów webpartów, niestety z "jakiegoś" powodu zawsze usunwałem tylko widocznego webpart'a, a niewidoczny zostawał na stronie. Nie mogłem też zrozumieć skąd w kolekcji WebParts jest tyle elementów.



Podglądam webpart'a


W celu wizualizacji mojego problemu, utworzyłem nową witrynę przy użyciu szablonu 'Blank'. Wybrałem tryb edycji strony i dodałem dwa takie same webparty.


Poniżej widać sztuk dwie "Html Form WebPart".



Zamykamy drugą instancję webpart'a.


I wtedy jako użytkownik widzę tylko jednego webparta. I niestety ciągle zapominam, że webpart'y mogą żyć w najlepsze będąc zamknięte. Teraz krótko o tym, jak sobie uświadomiłem, że użytkownik może zamykać webpart'y, a ich instancje są dalej dostępne z poziomu API, no i oczywiście z poziomu edytora webpart'ów w UI (pojawia się wtedy nowa kategoria Closed Web Parts).


Odkrycie zamkniętego webpart'a


W końcu z braku pomysłów napisałem skrypt w Powershell'u który wyświetlił wszystkie instancje webpart'ów wraz z ich właściwościami.

#DumpWebpartContent.ps1
$site = Get-SPSite "http://webapp/sites/myteam"
$web = $site.RootWeb;
$wpManager = $web.GetLimitedWebPartManager("Default.aspx", [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
foreach($webpart in $wpManager.Webparts)
{
 #this will dump webpart members content
 $webpart
}
$wpManager.Web.Dispose();
$wpManager.Dispose();



Zapisałem informacje zwrócone przez skypt i uruchomiłem WinMerge, żeby porównać dwie instancje webaprtów.



Okazało się, że jedną z właściwości, którymi się różnią sie jest IsClosed. Widoczne webparty mają ją ustawioną na FALSE, a te które są "zamknięte" przez użytkownika mają tą właściwość ustawioną na TRUE. Nagle mnie oświeciło, że ten dodatkowy webpart w kolekcji WebParts to właśnie zamknięte cudo.

Może zamiast uruchamiania tych skrytów Powershell'a powinienem pójść na kawę do kuchni, sam już nie wiem. Decyzja należy do czytelnika.

Hope this helps.

Brak komentarzy:

Prześlij komentarz

Uwaga: tylko uczestnik tego bloga może przesyłać komentarze.