31. spotkanie WG.NET

26 września, tradycyjnie o godzinie 18.00 rozpoczęło się 31. spotkanie WG.NET. Także i tym razem było niezwykle miło i ciekawie :)

Pierwsze wystąpienie należało do Kuby Binkowskiego i było rozwinięciem tematu zaczętego na Zine Day, a mianowicie dotyczyło AOP i DI – „AOP i DI wg P&P, czyli Unity i Policy Injection Application Block”. Tak jak w tytule Kuba opowiadał o dwóch frameworkach – PIAB i Unity. Temat jest niebanalny, więc wykład wymagał dużo skupienia. Nasz prelegent jednak się spisał i przedstawił temat bardzo zgrabnie. PIAB przedstawione było na bazie (powiedzmy :P) biznesowej aplikacji, natomiast Unity zdominowane było przez kulinarne skojarzenia, za co należy się Kubie lincz (18.00 to jak słusznie zauważył zdaje się Kuba Gutkowski pora kolacyjna!) :) Wyczerpanie tematu w godzinnym wykładzie jest niemożliwe, jednak wydaje mi się, że możliwości i filozofie obu frameworków zostały bardzo dobrze zaakcentowane. Brawo Kuba! :)

Po pierwszym wystąpieniu, tradycyjnie już była krótka przerwa na pogadanki. Jak zwykle można było ją spędzić bardzo miło. Wydaje mi się, że pomysł z przerwami na networking się przyjął i jest naprawdę doskonały!

„Praktyczny przegląd możliwości TFS 2008” – tak brzmi tytuł drugiego wykładu przeprowadzonego przez Marka Byszewskiego. Znów temat bardzo obszerny ale i bardzo ciekawy. Mam wrażenie, że bardzo zainteresował całą publikę :) Prezentacja była bardzo rzeczowa i zawierała praktyczne same przykłady i pokazy – czyli to co programiści lubią najbardziej :) Mam nadzieję, że temat będzie jeszcze rozwijany! Gratulacje za świetną prelekcję! Osobiście lubię ten bardzo spokojny styl, w którym Marek prowadzi wystąpienia :)

Tyle z 31. spotkania. Żal tylko, że następne, 32. spotkanie WG.NET prawdopodobnie dopiero za miesiąc!

Bloggers Underground

Już 7 października o godzinie 19.00 w jednym z lokali na warszawskiej starówce odbędzie się pierwsze wydarzenie pod nazwą „Bloggers Underground” – spotkanie społeczności blogerów piszących o technologiach Microsoft.

Formuła spotkania jest bardzo prosta – kilka wystąpień po 10 minut, podczas których można opowiedzieć o ciekawym wydarzeniu związanym z prowadzeniem bloga lub opisać ciekawe „case study”. To doskonała możliwość spędzenia wieczoru przed konferencją Microsoft Technology Summit 2008 w luźnej atmosferze wraz z innymi specjalistami IT i programistami. Zgłoszenia, pomysły oraz sugestie prosimy przekazywać drogą mailową.

Ilość miejsc jest limitowana i tylko zaproszeni goście mają wstęp na spotkanie, dlatego warto się śpieszyć z decyzją.

Zapraszamy na oficjalnego bloga imprezy, na którym publikujemy najświeższe informacje.

Do zobaczenia 7 października!

Bloggers Underground: oficjalna strona wydarzenia

Źródło: Codeguru.pl

Wszystko na to wskazuje, że i ja tam będę :) Nie wiem jeszcze tylko o czym opowiedzieć. Prawodopodobnie opowiem historię startupu mojego bloga :) Do zobaczenia!

ASP.NET MVC – autoryzacja użytkowników dla leniwych

Jeśli chcemy ograniczyć użytkownikom dostęp do różnych funkcjonalności naszej strony napisanej w ASP.NET MVC możemy skorzystać z przydatnych Membership Providerów (tak jak w przykładowej aplikacji MVC), możemy też zainteresować się czymś takim. Również kuszącą opcją jest skorzystanie z (mniej lub bardziej rozbudowanej) Forms Authentication znanej dobrze z „czystego” ASP.NET. Ja skusiłem się na tę ostatnią opcję, gdyż chciałem uzyskać efekt minimalnym nakładem pracy.

Jeśli prowadzicie blog, jedyne czego Wam potrzeba, to ograniczyć „anonimowym” dostęp do pewnych stron i akcji (jak np. dodawanie nowych notek), a dla siebie zatrzymać pełne uprawnienia. W tej sytuacji moje minimalistyczne rozwiązanie wydaje się być rozsądne :) Do rzeczy!

Na początek, w głównym pliku Web.config naszej aplikacji musimy dodać:

<authentication mode=”Forms />”

Aby nasza aplikacja wiedziała, czego od niej chcemy ;) Teraz należałoby stworzyć zwykły widok-formularz, w którym umieścimy pola login i hasło oraz odwołanie do odpowiedniej akcji, na przykład:

<form action=”/Admin/Authenticate/” method=”post”>

To znaczy, że po wciśnięciu przycisku submit uruchomiona zostanie akcja podłączona pod route (to wszystko można ustawić w Global.asax) „http://naszaplikacja.com/Admin/Authenticate/” przekazując przy tym wartości pól Login i Password. Proste, prawda? Teraz należałoby obsłużyć żądanie w kontrolerze. Przykładowa akcja poniżej:

[AcceptVerbs("POST")]
public ActionResult Authenticate(string Login, string Password)
{
if (!ZaawansowaMetodaAutoryzacji())
throw new Exception();
else
{
FormsAuthentication.SetAuthCookie("Admin", false);
return Index();
}
}

Bardzo ważna jest tutaj linia:

FormsAuthentication.SetAuthCookie(„Admin”, false);

To ona spowoduje, że zostaniemy autoryzowani jako użytkownik „Admin”. Drugi parametr („false”) działa jak znane pole „Remember me”, więcej do poczytania tutaj. Fajnie, prawda?

Teraz pozostaje nam już tylko oznaczyć odpowiednie akcje jako chronione. To ważne, chrońcie akcje a nie strony! Odpowiedź czemu zdaje się być oczywista. W dobrze napisanej aplikacji MVC każdy widok (każda strona) renderowana jest po przejściu przez kontroler, a więc przez odpowiednią akcję. Jeśli zabronimy „anonimowym” dostępu do odpowiednich akcji uzyskamy niemal 100% pewność, że nie obejrzą oni danej strony, ani nie wywołają nieprzeznaczonej dla nich metody (np. tworzącej nowy wpis na blogu) :) Jak zabronić dostępu użykownikowi do danej metody (akcji)? To bardzo proste. Wystarczy metodę oznaczyć atrybutem PrincipalPermission. Na przykład:

[PrincipalPermission(SecurityAction.Demand, Name = "Admin")]
[AcceptVerbs("POST")]
public RedirectToRouteResult AddEntry(string Title, string Text)
{
dataContext.AddEntry(Title, Text);
return RedirectToAction("Recent", "Blog");
}

Dzięki temu metoda – wpis może być dodany tylko przez użytkownika „Admin”. W taki sposób oznaczamy wszystkie metody, do których chcemy dodać restrykcje. To tyle! Tym sprytnym sposobem nasza aplikacja jest chroniona w bardzo prosty sposób :)

Źródła mojego bloga w końcu dostępne! :)

Po wielu zapowiedziach w końcu są :) Źródła mojego bloga (hLog) dostępne do ściągnięcia w dziale Projekty. Jest to mój pierwszy projekt w ASP.NET MVC i w ogóle w ASP.NET. Jestem więc otwarty na sugestie, propozycje, uwagi i krytykę – w komentarzach bądź via dział Kontakt. Zachęcam do ściągania! :)

PS. Mój feed jest teraz obsługiwany przez FeedBurner. Wszystkich aktualnych subskrybentów prosiłbym o zmianę adresu na http://feeds.feedburner.com/LukaszSowa/ a niesubskrybentów o subskrybcję :)

StackOverflow.com otwarte

Stack Overflow to dzieło dwóch, całkiem znanych w świecie inżynierii oprogramowania osobistości – Jeffa Atwooda i Joela Spolsky’ego. Czym jest Stack Overflow? W skrócie, jest to strona, na której można zadać pytanie dotyczące programowania i otrzymać fachową odpowiedź :) Przynajmniej takie są założenia.

Po zadaniu pytania wszyscy mogą na nie odpowiadać oraz głosować na inne odpowiedzi (zarówno na + jak i na -). Odpowiedź z największą ilością plusów wędruje na samą górę. Proste i mogłoby się zdawać – mądre. Istnieje również system reputacji i odznaczeń, aby wyróżniać użytkowników.

Teraz będzie moja osobista opinia. Myślę, że na mało wyrafinowane pytania łatwo będzie tam dostać odpowiedź, gorzej ze znalezieniem już istniejącego wątku. Istnieje co prawda system tagów i wyszukiwanie, ale to chyba za mało. Jeśli nasz problem będzie krytycznie ważny, to chyba mimo wszystko nie jest to najlepsze miejsce do znalezienia odpowiedzi ;) Choćby dlatego, że nie ma tam możliwości dyskusji, zamieszczania załączników itd… Sam być może skorzystam jeśli moje pytanie będzie szybkie i łatwe do zrozumienia. Póki co, traktuję tę stronę jako zapychacz czasu – tj. wchodzę, gdy mam „międzyczas” i czytuję sobie niektóre pytania korzystając z tagów c#, asp.net, .net. Czasem można dowiedzieć się czegoś ciekawego, albo komuś pomóc :)

Aktualnie na stronie jest bardzo duży ruch. Ludzie pytają o wszystko. Począwszy od bardzo wyspecjalizowanych pytań odnośnie konkretnych funkcji, aż do wypisywania swoich ulubionych książek o programowaniu. Co tu więcej pisać, zachęcam do samodzielnego zapoznania się ze stroną. Poniżej parę linków.

Stack Overflow
Jeff Atwood o Stack Overflow
Joel Spolsky o Stack Overflow
Zabawny blog, krytykujący Stack Overflow i jego autorów :)

UPDATE: Stack Overflow jest napisany w oparciu o ASP.NET MVC :) Miło widzieć tak duży, publiczny projekt oparty na tej technologii.

Przymusowa migracja zakończona!

Uff, wczoraj udało mi się zakończyć prace nad nową wersją mojego bloga i oto jest :) Na pierwszy rzut oka nie widać wielu zmian, ale naprawdę są. Teraz powinno obyć się już bez niespodzianek, przerw w działaniu i takich tam :)

Zmiany które zaszły:

Już niedługo udostępnię źródełka :)

Transformacje w WPF

W lipcu przyszło mi wykonywać dla pewnej firmy projekt łudząco przypominający zastosowanie Microsoft Surface. W mojej gestii leżało napisać program, który na podstawie przyjmowanych od panelu dotykowego współrzędnych będzie manipulował (transformował) obrazki. Ot, taki terminal, na którym klienci mogą sobie w przyjemny sposób pooglądać zdjęcia produktu. Przy okazji tego projektu zasięgnąłem poważnej lekcji WPF-a i długo zmagałem się z transformacjami graficznych obiektów – dlatego stwierdziłem, że warto napisać o paru aspektach tego zagadnienia :)

Wygodne transformowanie obiektów graficznych w WPF-ie to jedno z dobrodziejstw, które owa technologia oferuje, w szczególności jeśli zestawić ją z WinForms i GDI. Transformować możemy obiekty wszystkich klas, które dziedziczą po UIElement. Każdy taki obiekt posiada 2 właściwości: RenderTransform i LayoutTransform do której przypisujemy naszą transformacje. Czym różnią się te właściwości? Można o tym przeczytać tu albo uruchomić krótkie demo (koniecznie w IE), dostępne tu.

Teraz może nieco o transformacjach. Dostępnych typów transformacji jest cztery:

  1. RotateTransform – obrót o podany kąt (w stopniach) i podany środek obrotu (punkt)
  2. ScaleTransform – skalowanie, w punkcie skalowania, w dwóch płaszczyznach (X i Y) o podanej skali (oddzielnie X i Y); wartości >1 powiększają a wartości należące do przedziału (0;1) pomniejszają
  3. SkewTransform – „skośne” transformowanie o podane kąty (X i Y) oraz środek „skosowania” ;) – służy często do tworzenia iluzji trójwymiarowości
  4. TranslateTransform – najzwyklejsza translacja o wektor – wymagane są dwie współrzędne wektora

Więcej polecam poczytać więcej na MSDN, są nawet ładne rysunki :)

Przechodząc do rzeczy, aplikowanie transformacji jest bajecznie proste. Załózmy iż mamy obiekt typu ImagearrowImage i chcemy go przesunąć o wektor [50,82]. Wystarczy jedynie napisać:

arrowImage.RenderTransform = new TranslateTransform(50,82);

i gotowe :)

W taki sposób możemy jednak dodać tylko jedną transformację. Co jeśli chcemy zaaplikować naszemu obiektowi całą grupę transformacji? Wystarczy wtedy skorzystać z klasy TransformGroup:

TransformGroup transformGroup = new TransformGroup();

i teraz:

transformGroup.Children.Add(rotateTransform);

transformGroup.Children.Add(translateTransform);

transformGroup.Children.Add(scaleTransform);

pozostaje zaaplikować grupę transformacji:

arrowImage.RenderTransform = transformGroup;

tadam! Gotowe :)

Na koniec chciałbym zaznaczyć, że transformacje mają na siebie wpływ np. pomniejszenie obiektu o połowe powoduje iż translacja o wektor [8,0] jest tak naprawdę translacją o wektor [4,0]. Chyba, że zrobimy najpierw translacje, a potem pomniejszanie. Tutaj należy pamiętać, iż dodawanie transformacji nie zawsze jest przemienne: kolejność translacji nie ma znaczenia – wynik zawsze będzie taki sam; co innego np. z obrotem. Dokumentacja niestety nie jest zbyt wyczerpująca w tej kwestii. Osobiście męczyłem się tydzień, żeby zrozumieć cały mechanizm współdziałania między transformacjami – trzeba być naprawdę bardzo uważnym. Dla przykładu – najbardziej „aktualne” (te które mają być zastosowane najpóźniej) transformacje należy wstawiać na początku, a nie na końcu kolekcji.

transformGroup.Children.Add(rotateTransform); transformGroup.Children.Add(translateTransform);

Taki kod spowoduje najpierw translacje, a potem obrót. Jeśli więc chcemy uzyskać efekt wielokrotnej transformacji przydatne staje się coś takiego:

transformGroup.Children.Insert(0, pewnaTransformacja);

To by było na tyle. Jeszcze nie jestem pewien, czy mogę, ale być może wspomniana aplikacja a’la Surface zostanie opublikowana na moim blogu :) Tymczasem polecam spojrzenie na podobną aplikację – napisaną w Silverlighcie. Jej kod źródłowy jest cennym przykładem stosowania transformacji :)

30. spotkanie WG.NET

Wczoraj, to jest 11 września w godzinach 18-21 odbyło się 30. spotkanie WG.NET, połączone z 23. spotkaniem PLSSUG. Jak zwykle było miło, ciekawie i bardzo „edukacyjnie” :)

Po krótkim wstępie, który dotyczył przyszłości (w tym, zapowiedź C2C ’09!) oraz nadchodzącego MTS-a zaczęła się część zasadnicza – prelekcje. Pierwsze wystąpienie przygotowane było przez Łukasza Skrzypczyńskiego i dotyczyło BizTalka. Prezentacja bardzo mi się podobała – interesujące wprowadzenie do tego niezbyt znanego narzędzia. Niewiele suchych faktów, a dużo dem :) Bardzo fajnie było posłuchać Łukasza (jakie to ładne imię :)), mimo iż zapewne BizTalka nigdy używać nie będę :)

W przerwie między wystąpieniami było 35 minut socjalizowania się :) Jak zwykle było bardzo miło i przyjaźnie – szczególnie przyjemnie rozmawiało się z Pawłem Potasińskim o studiach, Oracle’u i Microsofcie. Pozdrawiam :)

Druga prezentacja miała nieco tajemniczy tytuł „Pesymistyczna strategia blokowania danych” i prowadził ją Wojciech Sawicki. Wystąpienie dotyczyło współpracy użytkowników bazy danych – tj. kiedy blokować, a kiedy nie, dane które mogą ulec zmianie. Prelekcja była zabawna, świetnie prowadzona – bardzo mi się podobała, mimo iż była wybitnie SQL-owa :) Temat wzbudzał wiele emocji i jednostronne przemówienie często przeradzało się wręcz w mały panel dyskusyjny – super! :) Gratulacje dla Wojtka! Dodam jeszcze, że w mojej czteromiesięcznej karierze w grupie offline’owej zdarzyło mi się wiele SQL-owych prezentacji i o dziwo, mimo iż jestem bazodanowym „newbie” bardzo dużo (ale nie wszystko :P) z nich zrozumiałem i wyniosłem – także brawo dla prelegentów i PLSSUG za dobór odpowiednich ludzi :)

Po prelekcjach było króciutkie zakończenie i była pora zbierać się do domu. Najbliższe spotkanie mam nadzieje jeszcze we wrześniu. Już nie mogę się doczekać! :)

Niemiła niespodzianka hostedwindows.pl – kolejne zmiany

2 dni temu dostałem smutnego maila od supportu hostedwindows.pl:

Po przeszło dwóch latach udostępniania bezpłatnego hostingu stron WWW i aplikacji ASP.NET zmuszeni byliśmy podjąć decyzję o zakończeniu świadczenia usługi Free Hosting. Twoje serwisy WWW istniejące w ramach tej usługi utrzymywane będą do 7 października br. Po tym dniu w ramach HostedWindows.pl udostępniana będzie wyłącznie oferta komercyjna.

Niestety póki co nie widzi mi się wykupywanie komercyjnej oferty – czeka mnie więc migracja na coś innego, darmowego. Do tego czasu ze stroną mogą się dziać dosyć dziwne i bardzo różne rzeczy (to będzie znaczyło, że na czymś się bardzo nie znam :P). Jak to wszystko się skończy – na razie nie wiem. W każdym razie mogę obiecać, że mój blog nie zniknie z sieci :)

Tworzymy własny kanał RSS 2.0, czyli kodujemy!

Jeśli prowadzisz stronę z dynamiczną zawartością, to z całą stanowczością potrzebujesz udostępniać ją jako kanał informacyjny. Coraz więcej osób (w tym od niedawna ja ;)) przegląda niusy, wpisy na blogach tylko i wyłącznie używając syndykacji. Ba, myślę nawet, że wiele stron z powodzeniem istniałoby bez jakiegokolwiek layoutu, a jedynie jako feed :) Ale dosyć już spekulacji, do dzieła! :)

Istnieją dwa liczące się standardy kanałów są to Atom i RSS. Polecam zapoznać się z linkami z jakże niezawodnej wikipedii :) W tym miejscu wypadałoby zdecydować się na któryś standard. Ja opiszę przygotowanie feeda w RSS 2.0, ale nic nie stoi na przeszkodzie, żeby zdecydować się na Atom. RSS wydaje mi się nadal być popularniejszym (osobiste odczucie), ale Atom depcze mu po piętach.
Na początek wypadałoby utworzyć stronę o jakiejś wdzięcznej nazwie, np. Feed.aspx. To było proste, teraz jednak przechodzimy w końcu do kodu :) Nie będę się tutaj rozwodził nad specyfikacją gdyż można o niej przeczytać tutaj. Jeśli jesteś leniwy, to wikipedia przedstawia bardzo skrótowy opis i przykład, który jednak nam wystarcza. Oto fragmencik pliku generującego kanał z bloga, którego czytasz:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Feed.aspx.cs" Inherits="hLog.Views.Blog.Feed" %><%Response.ContentType = "application/xml";%><%@ Import Namespace="hLog.Models"%>


Łukasz Sowa - blog programisty .NET
http://lukaszsowa.pl
Feed z najnowszymi notkami
<% foreach(Entry entry in ViewData.Model) { %>

<![CDATA[<% Response.Write(entry.Title); %>]]>
]]>
]]>
]]>

<%} %>


Kod powinien mówić sam za siebie. Są wszystkie wymagane pola , a dodatkowo również , które jest bardzo przydatnym polem. Zwróć uwagę na formatowanie (wymagane pola, kolejność, umiejscowienie), gdyż nawet drobne odstępstwa od reguł mogą powodować poważne błędy. Mój blog, czego tutaj niestety nie widać, pobiera 10 najnowszych postów, a następnie osadza je w znacznikach. Wyjaśnienia wymaga jeszcze tajemnicza CDATA. Otóż podczas parsowania pliku, w wygenerowanej zawartości mogą znaleźć się elementy, które zaburzą układ znaczników, a co za tym idzie – cały nasz Feed wygeneruje się z błędem. Tu właśnie przychodzi z pomocą CDATA. Wszystko co znajduje się pomiędzy znacznikami CDATA jest ignorowane podczas parsowania – czyli nasze dane nie zaburzą znaczników.

No to pozostaje tylko odpalić stronkę i… ups! Kanał wyświetla się zapewne jako plaintext. Nie tego oczekujemy. Podgląd odebranego nagłówka wszystko wyjaśnia – przeglądarka traktuje dane, jako test. Musimy więc odpowiednio oprogramować zdarzenie Page_Load. Kod poniżej:

 protected void Page_Load(object sender, EvenrArgs e)
{
Response.ContentType = "application/xml";
}

Teraz nasza przeglądarka będzie wiedziała (dzięki zmodyfikowanemu nagłówkowi), że odczytuje XML.

Teraz już powinno wszystko działać. Voila! :) Ciesz się swoim własnym kanałem.

PS. To mój pierwszy stricte techniczny tekst, więc liczę na feedback i wyrozumiałość :)