Mhhh… w małych firmach, raczej każdy wie kto pod kim jest ;) jednak w dużych firmach, czy nawet wielkich korporacjach ta informacja wcale nie jest „łatwo” dostępna. Na szczęście z MOSS to nie problem ;)

Zaczynamy zabawę. Jednak na początku trzeba zebrać zabawki ;) Instalujemy SmartPart z CodePlex i z 12 HIVEISAPI zabieramy DLLki:

  • Microsoft.Office.Server.dll
  • microsoft.sharepoint.portal.dll
  • Microsoft.SharePoint.dll

Z przygotowanym wiaderkiem ruszamy do piaskownicy. Odpalamy VS 2005/2008 i tworzymy ASP.NET Web Application. Do referencji dodajemy nasze zebrane DLLki, zaś Default.aspx kasujemy! Dodatkowo, żeby sobie ułatwić deployment (IMHO ułatwić, nie wiem jak wam), ustawiamy podpisanie assembly kluczem SNK (nowym lub jednym z waszej biblioteczki, jeżeli taką posiadacie).

Tworzymy nowy plik, Web User Control i wypełniamy go następującym kodem:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyManager.ascx.cs" Inherits="Gutek.Samples.MyManager" %>
<%-- @ Control Language="C#" AutoEventWireup="true" Inherits="Gutek.Samples.MyManager, Gutek.Samples, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9bdd615dfd84016b" --%>
<%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
 
<%-- Wymagany Loader Profilii, bez niego kod nie zadziala. SharePoint szuka tego elementu. --%>
<SPSWC:ProfilePropertyLoader runat="server" ID="m_objLoader" />
<%-- Nasz literal na którym będziemy wyświetlać naszego Managera (lub Managera danej osoby...). --%>
<asp:Literal runat="server" ID="litMyManager" />

W kwestii wytłumaczenia:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="MyManager.ascx.cs" Inherits="Gutek.Samples.MyManager" %>
 
<%-- @ Control Language="C#" AutoEventWireup="true" Inherits="Gutek.Samples.MyManager, Gutek.Samples, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9bdd615dfd84016b" --%>

Te dwie linijki są tak jakby tymi samymi linijkami :) różnica polega na tym, że jeżeli będziemy chcieli naszą kontrolkę wykorzystać z MOSS to jak zostawimy CodeBehind to MOSS nam krzyknie, żę brak mu pliku źródłowego :( Dlatego zawsze dodaje ten kod poniżej, który odwołuje się do konkretnej klasy w konkretnym assembly.

<%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
 
<%-- Wymagany Loader Profilii, bez niego kod nie zadziala. SharePoint szuka tego elementu. --%>
<SPSWC:ProfilePropertyLoader runat="server" ID="m_objLoader" />

ProfilePropertyLoader jest kontrolką, która daje nam dostęp do profile użytkownika bez konieczności posiadania praw administratorskich. Bez tej kontrolki nic nam nie zadziała :( to co ona robi, to ładuje dane dotyczące danego użytkownika, do najważniejszych i najczęściej używanych jej własności można zaliczyć:

Deklaracji Literal’a nie będę tłumaczył ;)

Ok., to mamy stronę przygotowaną, teraz pora dodać nasz code-behind :) Otwieramy klasę od naszej kontrolki i dodajemy następujące usings:

using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint.Portal.WebControls;

Kod w sam sobie powinien być zrozumiały, jednakże zwrócę uwagę na dwie rzeczy:

protected void Page_Load(object sender, EventArgs e)
{
    StringBuilder myManagers = new StringBuilder();
    try
    {
        ProfilePropertyLoader loader = ProfilePropertyLoader.FindLoader(this.Page);
        UserProfile[] managers = loader.ProfileLoaded.GetManagers();
 
        for (int i = 0; i < managers.Length; i++)
        {
            UserProfile manager = managers[i];
 
            string accountName = (string)manager["AccountName"].Value;
            myManagers.AppendFormat("Uzytkownik: <b>{0}</b><br />", accountName);
 
            string preferredName = (string)manager["PreferredName"].Value;
            myManagers.AppendFormat("Nazwa wyświetlana: <b>{0}</b><br />", preferredName);
 
            string title = (string)manager["Title"].Value;
            myManagers.AppendFormat("Stanowisko: <b>{0}</b><br />", title);
 
            string email = (string)manager["WorkEmail"].Value;
            myManagers.AppendFormat("Emial: <b>{0}</b><br />", email);
        }
 
        this.litMyManager.Text += myManagers.ToString();
    }
    catch (Exception ex)
    {
        this.litMyManager.Text = "<b><i>Ups... cos poszlo nie tak :(</i></b><br />" + ex.Message;
    }
}

Kod w sam sobie powinien być zrozumiały, jednakże zwrócę uwagę na dwie rzeczy:

ProfilePropertyLoader loader = ProfilePropertyLoader.FindLoader(this.Page);
UserProfile[] managers = loader.ProfileLoaded.GetManagers();

Na początku tworzymy naszego ProfilePropertyLoader. Tak naprawdę MOSS w tym momencie szuka swojej kontrolki na stronie, jak ją znajduje to zwraca nam obiekt jak nie to mamy null. W tym przypadku tego nie obsłużyłem ;) ale jak chcecie poprawny kodzik to warto na to zwrócić uwagę.

Następnie to co robimy to pobieramy managerów przypisanych do aktualnie załadowanego profilu. Metoda GetManagers(), jest metodą dostępną w klasie UserProfile i zwraca ona managerów przypisanych do użytkownika – czasami w różnych firmach, jedna osoba może mieć kilku managerów. Jeżeli jesteście pewni, że może być tylko jeden to wywołajcie metodę GetManager().

Do podstawowych metod klasy UserProfile, można zaliczyć:

  • Commit – zatwierdza zmiany dokonane w profilu użytkownika.
  • CreatePersonalSite – tworzy My Site dla danego użytkownika.
  • GetCommonManager – zwraca managera, który jest także „Twoim” managerem. To znaczy, jeżeli nasz UserProfile przechowuje dane na temat osoby B, zaś my wywołujemy tą metodę, to zostanie zwrócony ten manager, który jest nade mną jak i nad osobą B.
  • GetDirectReports – zwraca podwładnych.
  • GetManager – patrz akapit wyżej.
  • GetManagers – patrz akapit wyżej.
  • GetPeers – zwraca osoby, które są w tej samej gałęzi pod tym samym managerem.
  • RefreshManagers – odświeża listę managerów.

Następnie w kodzie musimy pobrać odpowiednie właściwości użytkownika, dokładnie mówiąc to co nas interesuje na jego temat:

UserProfile manager = managers[i];
 
string accountName = (string)manager["AccountName"].Value;
string preferredName = (string)manager["PreferredName"].Value;
string title = (string)manager["Title"].Value;
string email = (string)manager["WorkEmail"].Value;

Dla przykładu pobrałem tylko kilka własności, jednak gdybyście chcieli się zagłębić to możecie pobrać wszystkie te dane, które skonfigurujecie w SSP dla MOSS. Czyli jednym słowem wszystkie własności obiektu użytkownika z AD plus te które sami zdefiniujecie.

No dobra, pora na ostatnie stylistyczne poprawki, robimy build i… gotowe! ;) chciałbym! Naprawdę chciałbym :) Musimy jeszcze z deployować nasze assembly do GAC oraz w INETPUB tam gdzie leży nasza strona MOSS stworzyć katalog usercontrols a do niego wrzucić nasz plik ascx. Jak go tam wrzucimy, komentujemy pierwszą linijkę zaś drugą należy od komentować .

Oczywiście jak to w MOSS bywa, robimy IISRESET, otwieramy naszą stronkę, klikamy na Site Actions | Edit Page i dodajemy SmaprtPart WebPart. Otwieramy jego tool’s pane i z combo box wybieramy naszą kontrolkę i klikamy OK. Tym razem koniec! :)

Teraz możemy odejść na 2-3 metry od piaskownicy, zawołać rodziców i pokazać im nasze zamczysko!

gutek_moss_501

A teraz :) jeżeli do URL strony dodacie query string accountname=PearlJamMike to :) załaduje się wam informacja na temat managera Mike :) Taki prosty bajer, a tyle można osiągnąć ;)

UWAGA: kod przedstawiony tutaj DZIAŁA TYLKO I WYŁĄCZNIE NA MOSS, nie zadziała on wam na WSS. Dzieje się tak, gdyż korzystamy z DLLek specyficznych dla MOSS, których nie ma w instalce WSS. Aktualnie z tego co mi wiadomo w WSS jedynym sposobem pobrania managera jest odpytanie AD!

PS.: Załączam kod do postu.

PS2.: W przyszłym tygodniu będę miał trochę wolnego czasu więc postaram się w końcu dodać brakujące Stored Procedures do artykułu o ograniczeniach SharePoint oraz postaram się w końcu opisać ListIteratora.

2 KOMENTARZE

  1. Czesto sie zdaza, iz w AD nie sa przechowywane informacje o managerze, np. ze wzgledu na polityke firmy zmiany w AD sa rzadsze niz w jakiejs osobnej bazie pracownikow.
    I wtedy w celu utworzenia struktury organizacji na bazie SPSa/MOSSa, wystarczy przeiterowac profile i kazdemu we wlasciwosci Manager obiektu UserProfile ustawic nazwe konta Managera i zatwierdzic przez up.Commit() aby ew. drzewo “zwierzchnosci” bylo dostepne jako odnosniki w publicznie dostepnym profilu.

    Problem: Jakie sa minimalne uprawnienia do wykonania tej operacji w MOSSie? W SPSie byly troche zbyt wysokie..

  2. @sg_mt

    Aktualnie nie mam dostepu do MOSS, postaram sie w pracy jakos go sobie szybko postawic. Ogolnie w MOSS, jest tak, ze zarzadzasz profilami poprzez Shared Services. Tam ustawiasz jakie pola i z skad maja bys pobierane. Nie musi byc to AD. Duzym plusem, pobierania tak danych jest to iz MOSS dba o to by byly aktualne porpzez synchronizacje danych.

    Ten sposob ktory opisales jest fajny, ale tu lepiej go nie wykonywac jezeli ma sie wlaczona synchronizacje z AD. Poporstu po okreslonym czasie Twoj MGR zostanie nadpisany.

    Co do uprawnien, zaby zaktualizowac pole uzytkownika A to albo musisz byc Site Admin, albo danym uzytownikiem A. Moge sie mylic co do Site Admin, jako ze mozliwe iz jest jakies jedno malutkie uprawnienie, ktore nalezy zaznaczyc na szczegolowych uprawnieniach – ale tego bez moss nie sprawdze.

    mam nadzieje, ze odp na pytanko. Wrazie czego daj znac.

Comments are closed.