niedziela, 28 lipca 2013

Log in as a different user in sharepoint 2013

Ten konkretny wpis, to zwykły link do innego bloga, ale zostawiam to tutaj, ponieważ ten blog jest również moim prywatnym notatnikiem.

heblobfarm.wordpress.com <-> sharepoint-2013-ui-log-in-as-a-different-user/

Layouts folder location in sharepoint 2010/2013

No i stało. Oficjalnie wyszedł długo oczekiwany następca sharepointa 2010, czyli sharepoint 2013. Zapewne posiada wiele ciekawych funkcji i udogodnień, natomiast pierwszą rzeczą, która rzuca się w oczy, to fakt, że projekty napisane w sharepoint 2010, które planujemy wdrożyć dla sharepointa 2013 powinny być skonwertowane na typ projektu 'sharepoint 2013'. Projekt po takiej konwersji nie może zostać użyty w 'sharepoint 2010'. W praktyce jesteśmy więc zmuszeni do stworzenia dwóch projektów obok siebie i wymuszenia, aby oba projekty posiadały wspólne pliki .cs (niestety, ale inne pliki, czyli aspx, ascx, css, js, xml, png, i cała reszta plików umieszczana zazwyczaj w 'layouts' musi być zdublowana i znajdować się w obu projektach).

Gdyby jednak tego było mało, to folder layouts w nowym sharepoincie nie nazywa się 'layouts/' (tak jak to było w sharepoint 2010), tylko... 'layouts/15/".
Na szczęście jest sposób, aby można było wykorzystywać te same pliki .cs w obu projektach. Oto on, czyli klasa UrlHelper:

  public class UrlHelper
    {

        public static string LayoutsUrl
        {
            get
            {
                PropertyInfo pi = typeof(SPUtility).GetProperty(
"ContextLayoutsFolder", BindingFlags.Public | BindingFlags.Static);
                if (pi == null)
                    return "/_layouts/";
                else
                    return String.Format("/{0}/", pi.GetValue(null, null).ToString());
            }
        }

        public static string ImagesUrl
        {
            get
            {
                PropertyInfo pi = typeof(SPUtility).GetProperty("ContextImagesRoot", BindingFlags.Public | BindingFlags.Static);
                if (pi == null)
                    return "/_layouts/images/";
                else
                    return String.Format("{0}", pi.GetValue(null, null).ToString());
            }
        }


        public static string ControlTemplatesUrl
        {
            get
            {
                PropertyInfo pi = typeof(SPUtility).GetProperty("ContextControlTemplatesFolder", BindingFlags.Public | BindingFlags.Static);
                if (pi == null)
                    return "/_CONTROLTEMPLATES/";
                else
                    return String.Format("/{0}/", pi.GetValue(null, null).ToString());

            }
           
        }
    }

W praktyce, wszędzie, gdzie odwołujemy się do katalogów związanych z 'layouts', zamiast wpisywać stringi, powinniśmy wykorzystać metodę klasy UrlHelper.

poniedziałek, 22 lipca 2013

Selenium - software testing framework for web applications

Przeglądając wykład Grzegorza Dudy podczas konferencji confitura 2012 pt. From Busy to Effective Developer odkryłem fajne, nowe narzędzie, które zademonstrował Grzegorz. Narzędzie nazywa się selenium i służy do testowania stron internetowych. O ile, nie wgłębiałem się szczegółowo w API tego narzędzia, to jego podstawowa funkcjonalność, dostępna jako plug-in do przeglądardki firefox służy do nagrywania/reprodukcji schematu poruszania się po stronie internetowej.

Czasami zdarza się bowiem, że aby odtworzyć błąd, trzeba się 'przeklikać' przez wiele formularzy (i dopiero wtedy podpiąć debugger). W takich właśnie momentach przydaje się Selenium. Za pierwszym razem, przeklikując się przez formularze włączamy opcję 'rejestrowania', a przy nast., okazji, gdy potrzebujemy wykonać identyczną operację tylko włączamy opcję odtwarzania poprzednio zapisanego scenariusza testowego.

Narzędzie dostępne jest na licencji Apache 2.0 więc spokojnie możemy z niego korzystać, a nawet rozwijać.

niedziela, 21 lipca 2013

Programming never changes (asp mvc)

Czyli... w końcu rozpocząłem moją przygodę z ASP MVC na poważnie. Rozpocząłem ją od wszelkiej maści tutoriali, jakie można znaleźć na oficjalnej stronie asp mvc. O ile pierwszy tutorial z asp mvc 4 (MvcMovie) poszedł gładko, to już w nast. z asp mvc 3 (MvcMusicStorew 5 części tutka wystąpiły błędy, a dokładniej "Using the same DbCompiledModel to create contexts against different types of database servers is not supported". Ale... od czego mamy stackoverflow.com ;)

Parafrazując słynny cytat z serii Fallout: Programming never changes

niedziela, 14 lipca 2013

Index oraz Index Klastrowany (Clustered Index)

Przygotowując się do głębszego zagłębienia się w temat ASP.NET MVC robię sobie powtórkę z starszego materiału, tj. asp.net oraz bazy danych. A skoro już jesteśmy przy temacie baz danych, to wypadało by wspomnieć m.in. o indeksach oraz ich typach występujących w bazie danych MS SQL.
Indeksy bazodanowe, podobnie jak indeksy w książkach służą do szybszego wyszukiwania interesujących nas informacji, dzięki czemu zdecydowanie zwiększają szybkość wyszukiwania danych z bazy danych, ale nieznacznie zwiększają czas zapisu/modyfikacji/usuwania danych, dlatego nie należy umieszczać ich ponad miarę. Indeks może zawierać maksymalnie 16 kolumn.

W bazie MS SQL występują dwa typy indeksów:
- indeks klastrowany (clustered index)
- indeks zwykły (non-clustered index)

Index klastrowany odpowiada za fizyczną reprezentację danych w bazie danych (fizyczny zapis danych na dysku twardym) oraz może być tylko jeden (dane mogą być poprawnie posortowane w strukturze B-drzewa tylko na jeden sposób). Każda operacja typu insert/update/delete na danych, na których jest założony index klastrowany powoduje fizyczne sortowanie B-drzewa z danymi.

Indeks zwykły (nieklastrowany) jest osobną strukturą danych, składowanych osobnie i posiadającym 'wartość' oraz wskaźnik do fizycznych danych które reprezentuje. Indeks zwykły, jeżeli tylko może wykorzystuje index klastrowany, aby zwiększyć efektywność przeszukiwania. W przypadku operacji insert/update/delete na danych, wartości indeksów zwykłych są aktualizowane. Na tabeli może być wiele indeksów zwykłych.

Przykład współdziałania indeksów dość dobrze wyjaśnia





Control State vs View State

Jak powszechnie wiadomo, aplikacje napisane w asp.net są bez stanowe, a wywołanie każdego postbacka (np. za pomocą naciśnięcia przycisku) powoduje usunięcie aktualnej strony i utworzenie nowej. Aby zachować informacje pomiędzy postbackami stosuje się m.in. mechanizmy 'Control state' oraz 'View state'. A jakie są pomiędzy nimi główne różnice?

a) View state można wyłączyć (jeżeli inny developer korzysta z Twoich kontrolek, to może wyłączyć w nich 'view state', przez co kontrolki przestaną działać).
b) Control state nie da się wyłączyć (jest zawsze włączony), ale posiada ograniczenie co do ilości danych, jakie można w nim składować (nigdy nie próbujcie składować 'Grid View' w Control State).

Linki:
'Control state vs View State' na forum asp.net
'Control state vs View State' na forum stackoverflow

sobota, 6 lipca 2013

LoggingService, czyli logowanie błędów w Sharepoint 2010

W pracy programisty bardzo ważne jest logowanie błędów. Gorsze od nie logowania błędów jest tylko błędne logowanie błędów (np. poprzez napisanie własnego logera, co niestety miałem już okazję widzieć w praktyce). Aby poprawnie logować błędy, najlepiej użyć jakiegoś gotowego rozwiązania.

W przypadku aplikacji typu sharepoint nie powinniśmy używać zewnętrznych bibliotek. Jak opisuje to avishnyakov za pomocą spdevlab.com:


Suggestion #0 – Do not use 3rd part logging framework

Even if you stick to log4net, NLog, EventLog or System.Diagnostic.Trace, or trying to invent your own wheel, then DO NOT EVER USE THAT STUFF AGAIN.
SharePoint has its own logging system called “Unified Logging System (ULS)“. If you still wonder why would you use ULS instead your lovely logging framework, then consider the following facts:
  • ULS is used by SharePoint, so if you used 3rd part logging, you would need to consolidate logs from few different sources
  • ULS can be easily configured from Central Administration as well as by PowerShell
  • ULS can write to Windows Event Log without elevated privileges (!)
  • ULS shrinks text log files on the hard drives (!)
  • ULS does not require web.config changes/modifications (!). That’s quite important concern for multi-server farm
  • SharePoint can aggregate ULS log (and not just logs..) from multiple servers to the logging data base (Usage and Health Data Collection Service Application)

Dlatego w rozwiązaniach typu sharepoint 2010 dużo lepszym rozwiązaniem jest napisanie/skopiowanie klasy LoggingService dziedziczącej po SPDiagnosticsServiceBase.
Takie rozwiązanie znajdziemy w wielu miejscach w sieci, więc wydaje się ono być najlepsze.

Sama klasa, wygląda następująco:
public class LoggingService : SPDiagnosticsServiceBase
{
 public static string DiagnosticAreaName = "My";
 private static LoggingService _Current;
 public static LoggingService Current
 {
 get
 {
 if (_Current == null)
 {
 _Current = new LoggingService();
 }
 return _Current;
 }
 }
 private LoggingService()
 : base("My Logging Service", SPFarm.Local)
 {
 }
 protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
 {
 List<SPDiagnosticsArea> areas = new List<SPDiagnosticsArea>
 {
 new SPDiagnosticsArea(DiagnosticAreaName, new List<SPDiagnosticsCategory>
 {
 new SPDiagnosticsCategory("WebParts", TraceSeverity.Unexpected, EventSeverity.Error)
 })
 };
 return areas;
 }
 public static void LogError(string categoryName, string errorMessage)
 {
 SPDiagnosticsCategory category = LoggingService.Current.Areas[DiagnosticAreaName].Categories[categoryName];
 LoggingService.Current.WriteTrace(0, category, TraceSeverity.Unexpected, errorMessage);
 }
}
natomiast jej użycie wygląda tak:

LoggingService.LogError("WebParts", ex.ToString);
Do przeglądania logów polecam program ULSViewer dostępny na mocy licencji  MICROSOFT PUBLIC LICENSE (Ms-PL)

Przydatne linki:
wpis Avishnyakov'a na spdevlab.com
wpis na blogu Waldka Mastykarza
wpis na blogu Jurgena Baurle