Ostatnio musiałem napisać na szybko kod, który miał przechodzić po wszystkich WebPartach na stronie i sprawdzić czy linki w nich zawarte prowadzą do poprawnego serwera. To co myślałem, że będzie proste okazało się zmorą programisty :) Dlatego też chciałbym się tym tutaj podzielić byście przypadkiem też się zbędnie z czymś takim nie męczyli :)

Otworzyłem sobie VS i stworzyłem projekt Command Line, w którym napisałem funkcje, której fragment wyglądającą mniej więcej tak:

SPSecurity.RunWithElevatedPrivileges
(
    delegate()
    {
        using (SPSite site = new SPSite(uniqueSiteId))
        {
            using (SPWeb web = site.OpenWeb(uniqueWebId))
            {
                using(SPLimitedWebPartManager manager = web.GetLimitedWebPartManager("default.aspx", PersonalizationScope.Shared))
                {
                    foreach(WebPart wp in manager.WebParts)
                    {
                        if(wp is ContentEditorWebPart)
                        {
                            ContentEditorWebPart cedwp = wp as ContentEditorWebPart;
                            // do some work
                            manager.SaveChanges(cedwp);
                        }
 
                        wp.Dispose();
                    }
                }
            }
        }
    }
);

I wszystko byłoby pięknie gdyby to mi zadziałało :) To znaczy, program wykonał się poprawnie i zakończył sukcesem, jednak zmian na stronie nie mogłem zaobserwować. Pomyślałem, że może jednak coś źle robię – szybkie wyszukiwanie w Google powiedziało, iż dobrze robię, a więc co mogło być nie tak?

Podłączyłem się debugerem pod kod by zobaczyć co jest nie tak. Okazało się, że mój wp jest zawsze ErrorWebPart i niczym innym. Zapytanie:

web.GetLimitedWebPartManager("default.aspx", PersonalizationScope.Shared).WebParts[0]

w oknie Immediate, zwracało:

A first chance exception of type ‘Microsoft.SharePoint.WebPartPages.WebPartPageUserException’ occurred in Microsoft.SharePoint.dll

a następnie wypisywało wszystkie informacje na temat ErrorWebPart. Skoro zwracało mi taki błąd, do zagłębiłem się w właściwości tego WebPart by odkryć własnośći ErrorType i ErrorText, które kolejno zwracały:

Error Type

Microsoft.SharePoint.WebPartPages.ErrorType.Unsafe

Error Text

This page has encountered a critical error. Contact your system administrator if this problem persists.

Zagłębienie się w Inner Exceptions dało mi za to taki wynik:

_COMPlusExceptionCode = -532459699

Tutaj już Google, zabardzo nie pomógł ;) Zaś nie chciało mi się już bardziej dociekać dlaczego się tak dzieję, choć zapewne dzięki WinDbg byłbym wstanie dowiedzieć się więcej.

Cofnąłem się więc do błędu z okna Immediate i w Google znalazłem informację taką iż SharePoint nie zezwala mi na dostęp do WebPart do póki:

  1. Web Part do którego chcę się dostać nie jest uznany za Safe;
  2. Mój kod nie jest uznany za Safe.

Biorąc pod uwagę te dwie wiadomości, zamieniłem swój kod na DLL Library a następnie podpisałem je i wrzuciłem do GAC. Do kodu dodałem jeszcze stronkę na której umieściłem przycisk Run i boom :) kod zadziałał :)

Widać nie wszystkie zabezpieczenia w SharePoint są złe ;) to po jakimś czasie mi się nawet spodobało, gdyż wiem iż Administrator za pomocą „brzydkiego programu” nie zrobi krzywdy WebPartom (ukłon w stronę Justyny ;)). Oczywiście dojście do rozwiązania trochę zajęło a błąd nie był jasny – ten Unsafe mógł nakierować, ale nie do tego stopnia, że bym stworzył stronę a DLL wrzucił do GAC :)

Może nowa wersja będzie miała… lepsze opisy błędów ;)

3 KOMENTARZE

  1. @Waldek

    moze sie zle wyrazilem, chodzilo wlasnie o osadzenie kodu w SharePoint, mozliwe ze wlasnie z tego powodu by posiadal on SPContext, ale na przyklad jezeli WebPart nie jest uznany za Safe w SharePoint i ma dostep do SPContext to SharePoint moze Ci zwrocic ErrorWebPart.

    Czyli chyba nie tylko SPContext tutaj jest “kluczem” ale takze zabezpieczenia kodu i Security Attributes zezwalajace na korzystanie z okreslonych elementow SharePoint w zaleznosci od kontekstu uruchomienia.

    Ale tak jak powiedzialem, nie analizowalem tego do konca, wiec moge sie momentami mylic :)

    Gutek

Comments are closed.