czwartek, 2 grudnia 2010

ASP.NET MVC na 30 spotkaniu PG.NET

Zapraszam wszystkich na 30 (niezła, okrągła liczba) spotkanie Poznańskiej Grupy .NET, które odbędzie się w czwartek 2 grudnia 2010 o godz. 18:00 w siedzibie firmy Cognifide (Aleja Wielkopolska 4, Poznań) - na której zaprezentuję Wam platformę ASP.NET MVC. Prezentacja będzie miała charakter wprowadzającą - rozjaśniający: czyli będziemy krok po kroku poznawali najważniejsze elementy ASP.NET MVC wersji 2, a także udogodnienia, które będzie (bo nie wydana jeszcze oficjalnie) zawierała w sobie trzecia wersja ASP.NET MVC

Rejestracja na spotkanie jest bezpłatna: Rejestracja @ Codeguru.pl

niedziela, 24 października 2010

StructureMapControllerFactory w ASP.NET MVC

Standardowa implementacja fabryki kontrolerów StructureMapControllerFactory może spowodować serię wyjątków zgłaszanych podczas próby utworzenia konkretnego kontrolera dla bieżącego żądania Http. Dzieje się tak dlatego, że domyślna tablica routingu aplikacji nie wyklucza przetwarzania plików statycznych takich jak np. favicon.ico – jest on wykorzystywany w standardowym template dla aplikacji ASP.NET MVC 2. Efekt tego jest taki, że podczas implementacji aplikacji wygenerowanej z tego template otrzymujemy wyjątek:

System.ArgumentNullException was caught
  Message=Value cannot be null.
Parameter name: key
  Source=mscorlib
  ParamName=key
  StackTrace:
       at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
       at System.Collections.Generic.Dictionary`2.ContainsKey(TKey key)
       at StructureMap.Util.Cache`2.get_Item(KEY key)
       at StructureMap.BuildSession.CreateInstance(Type pluginType)
       at StructureMap.Container.GetInstance(Type pluginType)
       at StructureMap.ObjectFactory.GetInstance(Type pluginType)
       at Komstar.Domains.Web.StructureMapControllerFactory.CreateController(RequestContext requestContext, String controllerName) in D:\…\…\Global.asax.cs:line 64
  InnerException:

Aby rozwiązać ten problem należy dodać do routingu aplikacji następujący wpis:

routes.IgnoreRoute("{favicon}", new { favicon = @"(./)?favicon.ico(/.*)?" });



Teraz powinno być cicho.


środa, 9 czerwca 2010

Visual Studio 2010 Pro Power Tools i problem z czarną skórką

Ukazała się pierwsza wersja świetnego dodatku do Visual Studio: Visual Studio 2010 Pro Power Tools. Nie chcę się powtarzać bo opis funkcjonalności można przeczytać np. tutaj. Jednak zauważyłem problem w przypadku czarnych schematów kolorów IDE, których jestem zwolennikiem. Największy problem jest z jednym z ciekawszych ficzerów, a mianowicie kolorowaniem parametrów metod w oknie podpowiedzi. U mnie sprawa wyglądała następująco:

darktheme

Na szczęście udało mi się znaleźć rozwiązanie problemu. Należy wejść w: Tools->Options->Fonts and Colors->Signature Help Tooltip Background oraz odpowiednio ztuningować kolor tła i czcionek zgodnie z własnymi upodobaniami :-)

Hołp dis help ;-)

czwartek, 3 czerwca 2010

extendedProtectionPolicy spowoduje, że Twoja aplikacja przestanie działać, czyli WCF + Windows 7 = CRASH

Straciłem ostatnio ładnych kilka godzin namierzając problem, który skutkował kompletnym zamknięciem się aplikacji zaraz po jej starcie. Co ciekawe problem pojawiał się jedynie na komputerach produkcyjnych: u mnie działało :-)

Otóż jeśli tworzysz dowolnego klienta WCF i posiadasz system Windows 7 jest niemal pewne, że Twój klient nie uruchomi się na innych systemach operacyjnych! Dlaczego? Problem tkwi w elemencie extendedProtectionPolicy, który “potajemnie” dodawany jest do pliku App.config.

Więc jeśli Twoja aplikacja kończy działanie błedem zaraz po stworzeniu obiektu proxy dla klienta WCF i nie masz pojęcia o co chodzi, to rozwiązaniem jest usunięcie tego elementu z pliku App.config.

Mnie uratowała sesja z WinDbg, gdyż obiekt proxy miałem tworzony z kontenera StructureMap zaraz na początku w mojej aplikacji i nijak nie szło zdiagnozować problemu na komputerach produkcyjnych na których nie było żadnego środowiska programistycznego. Jednocześnie przekonałem się jak zaciemnić debugowanie może zastosowanie IoC.

sobota, 29 maja 2010

NDepend 3 wchodzi na scenę!

O wersji v2 NDependa pisałem we wcześniejszym poście, jednak na sporo więcej uwagi zasługuje najnowsza, trzecia wersja tego narzędzia.

Co nowego w NDepend?

Największą i dla mnie osobiście najbardziej przydatną nową funkcjonalnością jest pełna integracja z Visual Studio 2005/2008/2010 IDE. Jeszcze nigdy używanie NDependa nie było tak naturalne w procesie tworzenia oprogramowania. Integracja wprowadza zupełnie nowy sposób pracy z kodem, gdyż do tej pory (przynajmniej w moim przypadku), statyczna analiza kodu przez NDependa była najefektywniejsza w połączeniu z Continuous Integration (analiza przeprowadzana przez VisualNDepend była przeprowadzana wyrywkowo, jak mi się przypomniało). Integrację z Visual Studio uważam za doskonały pomysł i nie spodziewałem się, że może być ona tak pomocna!

Jak to wygląda w praktyce?

Zacznijmy od zainstalowania dodatku do VisualStudio, który pozwoli na integrację NDependa z VS. Po uruchomieniu VisualNDepend.exe klikamy na przycisk instalacji:

ndepend install adin 

Po czym wybieramy do jakiego środowiska ma być wykonana integracja oraz jej typ.

install adin 2

Do wyboru mamy: pełną integrację oraz integrację light. Integracja light polega na tym, że z poziomu Visula Studio będziemy wykonywać polecenia np. CQL (Code Query Language), które zostaną przesłane i uruchomione w otwartej osobno instancji VisualNDependa. Moim zdaniem instalacja light sprawdza się najlepiej na komputerach z niewielkimi monitorami. Mnogość okien NDependa wymaga sporej powierzchni do pracy, a gdzieś jeszcze trzeba znaleźć miejsce na wyświetlenie kodu :-) Jeśli jednak dysponujemy nieco większym ekranem, a już najlepiej dwoma, trzema, czterema, (ma ktoś pięć???) monitorami, wtedy wersja Full będzie najlepszym wyborem.

Analizę czas zacząć

Do celów edukacyjnych przeanalizujmy zobaczmy NDependa trójkę w akcji. Jak mięso armatnie użyję biblioteki Sharpy. Sharpy to implementacja ASP.NET MVC ViewEngine podobna do Smarty dostępnego dla PHP. Jednak w tym momencie nie jest to istotne. Po załadowaniu źródeł należy podłączyć NDependa do otwartego pliku solution, co czynimy bezpośrednio z poziomu menu VisualStudio (przed samym załadowaniem należy wykonać Build projektu):

attach

W tym momencie NDepend automatycznie przeskanuje projekty i zaproponuje je do analizy (przypominam, że wersji v2  trzeba było “ręcznie” utworzyć projekt) i to już pierwsze, ogromne udogodnienie:

attach 2

Oczywiście nic nie stoi na przeszkodzie, aby dołączyć kolejne pliki, które nie znajdowały się w naszym solution. Upewniamy się, że checkbox “Run Analysis Now!” jest zaznaczony, po czym pozostaje kliknąć przycisk OK.

Po wykonaniu analizy NDepend generuje raport HTML, który pozwala na szybkie przejrzenie stanu w jakim znajduje sie kod, reszta szczegółów znajduje się już w IDE. Szybki przegląd uzyskamy za pomocą żółtego oka węża (a co!) znajdującego się w prawym, dolnym rogu IDE:

yellow

Po dwukliku na nim oczom naszym ukazuje się CQL Query Explorer:

cql

NDepend Search

NDepend Search, to kolejny feature, który jest mega użyteczny. Mimo, że VS 2010 wprowadza możliwość “inteligentnego” wyszukiwania po nazwie metod, to NDepend Search (wywalasz z menu NDepend/NDepend Search) potrafi wyszukiwać po nazwie metody, typach, polu, assembly, przestrzeni nazw, a na dodatek pokazuje w oknie wyszukiwania złożoność danej metody / typu, a przy tym działa bardzo szybko!

search

Gdy jednak potrzebujemy bardziej rozbudowanego wyszukiwania pod względem złożoności wystarczy zaznaczyć po polu wyboru Serach by “Complexity”, a do dyspozycji będziemy mieli opcje służące do szybkiego odfiltrowania interesującej nas skali złożoności:

search 2

NDepend Class Browser + podgląd na żywo

Kolejnym przydatnym okienkiem jest NDepend Class Browser, który oprócz swojej podstawowej funkcjonalności jaką jest ułatwienie nawigowania po klasach i ich składowych, dodatkowo komunikuje się z pozostałymi oknami np. Dependency Matrix, Metrics itd, dzięki czemu po najechaniu na klasę w oknie Class Browser-a otrzymujemy informację np. o jej zależnościach w oknie Dependency Matrix:

class browser

Podsumowanie

Nowa wersja NDepend-a wnosi rzuca zupełnie inne światło na to narzędzie. Dzięki doskonałej integracji ze środowiskiem programistycznym pozwala na uruchomienie analizy w dowolnym wręcz momencie, a dodatkowe funkcjonalności takie jak chociażby wspomniany NDepend Search znacznie przyśpieszają codzienną pracę ze złożonym kodem. Sporo wody w Warcie upłynie zanim Visual Studio będzie wyposażone w taki kombajn.

Strona NDepend.com

NDdepend Features

Obsługa prawna Poznań

środa, 26 maja 2010

Użyteczny skrypt w Powershell

Jak za pomocą skryptu powłoki Powershell skompilować pliki solution znajdujące się w bieżącym folderze i jego podfolderach? Oto skrypcik, który do tego wykorzystuję:

foreach($file in get-childitem -filter *.sln -recurse)
{
echo Kompiluje $file.FullName
\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe /t:build /p:Platform="Any CPU" /v:q /nologo $file.FullName
}

Czyli skrypt doskonale nadaję się do tzw. buildAll :-)

sobota, 15 maja 2010

Debugowanie ścieżek ASP.NET MVC: Routes Debugger step by step

errorroad Routing ASP.NET MVC może zrobić sporo zamieszania, jeśli w naszej aplikacji korzystamy z zaawansowanego sterowania pomiędzy kontrolerami i odpowiadającymi im widokami. Dla dużych aplikacji (w obecnej chwili pracuję nad taką, która posiada ponad 120 kontrolerów – i nie ma tu problemów z refaktoryzacją) odpowiednie pokierowanie przepływem żądań to całkiem skomplikowany problem.

Są dwie metody debugowania ścieżek:

  1. Metoda empiryczna, czyli zmieniamy tabelę ścieżek, klikamy F5, po czym zamykamy oczy.
  2. Za pomocą biblioteki RoutesDebug – i tą metodę opiszę za chwilę.

RoutesDebug, czyli

RoutesDebug to pojedyńcza bilblioteka dostępna za darmo, która po dołączeniu do naszej aplikacji MVC oraz odpowiednim skonfigurowaniu (co jest dziecinnie proste) stanie się domyślnym RouteHandlerem.

Czyli zaczynamy

1. Pobieramy bibliotekę RoutesDebug.dll

2. W Visual Studio dodajemy referencję do niej w naszej aplikacji ASP.NET MVC

add_ref

3. Czas na rejestrację naszego nowego RouteHandlera. Przechodzimy do pliku Global.asax.cs i dodajemy jedną (!) linijkę:

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterRoutes(RouteTable.Routes);

//Powstań RoutesDebugerze:
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);

}

To wszystko. Teraz po uruchomieniu aplikacji powinniśmy ujrzeć stronę na, której prezentowana jest tablica ścieżek w naszej aplikacji.

routesdebug1

Tak naprawdę to jest to nasza konsola testowa :-) Ok, dla przykładu stworzyłem bardzo prostą aplikacyjkę, która zawiera następujące rejestracje scieżek:


public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(null, "Articles/{id}",
new { controller = "Articles", action = "Show" },
new { id = @"\d{1,9}" }
);

routes.MapRoute(null, "Articles/Show/{id}",
new { controller = "Articles", action = "Show" },
new { id = @"\d{1,9}" }
);

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

}

Do kontrolera Articles będziemy dopuszczać jedynie ścieżki które spełniają następujące wymagania:

  • Zawierają numer artykułu, który za pomocą prostego wyrażenia regularnego testowany jest, czy jest liczbą
  • Jeśli nie podamy nazwy metody, to przyjmujemy, że chodzi o metodę Show

Natomiast w konsoli testowej widzimy, że dla wywołania ścieżki: http://localhost/Articles/Show/1 pasujące są wpisy w tablicy:

  • Articles/Show{id}
  • {controller}/{action}/{id}

gdzie jako parametr przekazujemy nasz ID, czyli tutaj liczbę 1, kontroler to ArticlesController, a akcja to Show. Ale w naszym przykładzie zarejestrowałem także scieżkę, w której podanie nazwy akcji jest opcjonalne, przetestujmy więc ją:

http://localhost/Articles/1234

routesdebug3

czyli ścieżka także została rozpoznana, a pusta nazwa akcji została automatycznie uzupełniona przez wywołanie akcji Show, zgodnie z tym co podaliśmy w naszej tablicy routingu. Pozostał ostatni test, czyli test na niepoprawne dane, wpisujemy http://localhsot/Articles/darek –> to nie jest liczba :-)

routesdebug4

ścieżki nie zostały dopasowane, czyli wszystko działa.

piątek, 26 lutego 2010

AutoMapper. A co jeśli w naszym kodzie brak konwencji?

 copier Automapper jest biblioteką ułatwiającą konwersje między dwoma typami. Wykorzystując wspomnianą bibliotekę nie ma już konieczności pisania przydługiego kodu własnych konwerterów. Jak to się dzieje, że Automapper potrafi z typu:

public class BlogPost
{
    public string Title;
    public string Description;
    public string Body;
    public int Level;
    public DateTime CreationDate;
}

wyczarować np. klasę?:

public class BlipPost
{
    public string BlipBody;
    public DateTime DateOfBlip;
}

za pomocą wywołania jednej linijki kodu?:

//konwertujemy obiekt myPostObject z typu źródłowego (BlogPost) do typu docelowego (BlipPost)
Mapper.Map<BlogPost, BlipPost>(myPostObject); 

Otóż domyśla się on - za pomocą ogólnych konwencji nazewniczych - jakiemu typowi z klasy docelowej (BlipPost) będzie odpowiadał typ z klasy źródłowej (BlogPost). Świetnie. Jednak niechaj będzie błogosławiony ten, którego kod konwencji się trzyma. Prosty przykład, dla którego Automapper polegnie na samym wejściu:

public class Osoba
{
    public string Imie;
    public string NazwiskoRodowe;
    public string Nazwisko;
    public DateTime Urodziny;
}

Uwierzcie lub nie, ale Automapper nie da rady sobie zmapować tak prostej klasy na nic – jedynym efektem jego pracy będzie przepiękny wyjątek mapowania.

Wstań, powiedz nie jestem sam…

Można by Automapera o kant … potłuc, gdyby nie umożliwiał poradzenie sobie z podobnymi problemami.

Z pomocą przychodzi własny TypeConverter, który po zaimplementowaniu jednej metody Convert będzie płodził nowe klasy docelowe w sposób jaki mu powiemy.

public class ToBlipPostConverter : ITypeConverter<BlogPost, BlipPost>
{
#region ITypeConverter<BlogPost, BlipPost> Members

public BlipPost Convert(ResolutionContext context)
{
    BlogPost old = context.SourceValue as BlogPost;
    //if old != null
    var blip = new BlipPost();
    blip.Id = old.Id;
    blip.Data = old.DataPosta;
    blip.Level = old.Poziom;
    blip.Body = old.Tresc;
    
    return blip;
}

#endregion
}

Teraz wystarczy jedynie poinformować Automappera do używania naszej klasy konwertera dla podanych typów:

Mapper.CreateMap<BlogPost, BlipPost>().ConvertUsing<ToBlipPostConverter>();

Pisanie własnych konwerterów nieco mija się z celem, jednak sygnalizuję tylko problem na jaki może się natknąć deweloper.

No i tyle. Więcej można przeczytać na stronie projektu: Type Converters.

środa, 17 lutego 2010

Konferencje .NET w najbliższym czasie

26 marzec 2010 (piątek) Poznań 4Developers
4Developers to konferencja dla programistów tworzona przez programistów. Jest to największe przedsięwzięcie tego typu w Polsce – 700 uczestników, 4 równoległe ścieżki i ponad 30 prelegentów. 4Developers to profesjonalna, techniczna konferencja przeznaczona dla developerów i managerów projektów, kadry kierowniczej działów informatycznych, a także wszystkich studentów zainteresowanych programowaniem. Zapraszamy do dyskusji, wymiany doświadczeń i szukania rozwiązań dla wyzwań związanych z tworzeniem i rozwijaniem oprogramowania. 4Developers podzielona jest na cztery niezależne ścieżki związane z technologiami i problemami spotykanymi w nowoczesnych firmach zajmujących się produkcją oprogramowania [źródło 4developers]
- Ja będę tam!

17 kwiecień 2010 (sobota) Warszawa Communities2Communities 2010
C2C to doskonała okazja do spotkania i wysłuchania sesji najwyższej klasy specjalistów z Polski i ze świata, do wymiany doświadczeń i spotkania osób o podobnych zainteresowaniach.Tegoroczna konferencja, podobnie jak ta z ubiegłego roku, obejmuje aż trzy ścieżki tematyczne: przeznaczoną dla profesjonalistów IT, SQL Server oraz .NET. Na każdą ze ścieżek przypada pięć sesji - każda z nich będzie prowadzona na poziomie 300-400 wg skali MSFT, w profesjonalny sposób, przez najlepszych specjalistów, bez zbędnego marketingowego bełkotu. Jak udowodniła zeszłoroczna konferencja, sesje na poszczególnych ścieżkach były na podobnym poziomie jak te prowadzone na konferencjach typu TechEd czy MTS. [Żródło C2c]
- Ja będę tam!

czwartek, 4 lutego 2010

Offtopic: Firefox jest wszędzie

Dziś zwróciłem uwagę na dziwnie wyglądający przycisk Start Windows 7:

1

Pomyślałem sobie: gdzieś już widziałem ten kawałek wystający poza obręb ikony… Szybkie nałożenie podejrzanej ikony (znam jedną ikonę z ogonem):

2

… i jeszcze troszkę wyostrzamy ….

3

I dostaliśmy podpalonego lista. Tylko skąd on tam się wziął?

środa, 20 stycznia 2010

No i Visual Studio 2010 Beta 2 sie popsuło. Samo :-(

UntitledZ tego co pamiętam, to zostało mi jeszcze ok 130 dni testów. Będę żądał zwrotu pieniędzy lub wymiany na nowe.

czwartek, 14 stycznia 2010

Mój ASP.NET MVC stack


Postanowiłem spisać technologie, biblioteki, które używam w pracy z projektami ASP.NET MVC, ewentualnie “nowinki”, które zostały przetestowane w boju, ale ze względu na silną obsadę czekają na lepsze czasy i napewdno niedługo zostaną przeze mnie ponownie użyte. Oto one, zaczynająć od "pierwszego składu":


Architektura

  1. S#arp Architecture: podstawowy stack, który zawiera w sobie wszystko to, co potrzebne jest do stworzenia aplikacji ASP.NET MVC. Korzysta z Castle.Windsor co podmieniam na Ninject.
  2. NHibernate, doskonale wszystkim znany ORM
  3. Linq2SQL, tam gdzie nie ma NHibernate :-)
  4. Fluent Nhibernate biblioteka konfiguracji NHibernate bez konieczności użycia plików XML oparty o konwencję / Fluent Interfaces.
  5. Ninject jako lekki framework DI / IoC.
  6. MVCContrib: projekt rozszerzający standardową funkcjonalność dostępną w gołym ASP.NET MVC
  7. jQuery, jQuery UI, jQuery plugins: biblioteka javascript, zbiór kontrolek JS, chyba każdemu znana.

Poczekalnia

  1. Entity Framework 4, jako zamiennik NHibernate. Zauważyłem, że EF idzie w całkiem fajną, ciekawą stronę umożliwiając MDD, dobrze integruje się z VS. Myślę, że niedługo będzie poważną alternatywą dla NHibernate.
  2. Spark View Engine, jako zamiennik standardowego view engine. Fajne rozwiązanie PartialViews, daje mniejszy bałagan w kodzie widoku.
  3. FubuMVC, framework implementujący wzorzec Front Controller
  4. MVCTurbine: “The whole purpose of MVC Turbine is to speed your MVC development by having the plug-in handle all churn of the runtime and allow you to focus on what your application needs to do, rather than how to do it.”

Coś byście dorzucili? :-)

środa, 13 stycznia 2010

Wzorzec “POST Redirect GET” w ASP.NET MVC

Jednym z największych problemów w aplikacjach internetowych jest podwójne przesłanie danych za pomocą metody POST na szczęście prawidłowo korzystając z mechanizmów ASP.NET MVC można się przed tym obronić – ale o tym za chwilę. Na początek krótkie wyjaśnienie tego w czym cały problem.

Wyobraźmy sobie formularz w którym podajemy: Numer karty kredytowej, datę jej ważności, kwotę w eurogąbkach, którą przelewamy na konto oraz przycisk “Wyślij”, czyli standardowy mechanizm płacenia za płatne treści (taaak wiadomo jakie :-) ) w Internecie.  Formularz w oparciu o metodę POST prześle dane do serwera, gdzie zostanie odpalona jakaś skomplikowana logika, którą nie będziemy się teraz przejmować. Efekt jest taki, że na naszym koncie mamy mniej eurogąbek niż mieliśmy jeszcze minutę temu. Wszystko pięknie, ale po drodze coś mogło pójść nie tak i nie otrzymaliśmy informacji zwrotnej, że przelew się udał. Co gorsza strona może prosić o odświeżenie znanym chyba każdemu użytkownikowi, najczęściej niepoprawnie zaimplementowanych stron, komunikatem:

com

Co zrobi przeciętny użytkownik? Tak: kliknie przycisk Prześlij ponownie. I to kosztowny błąd, bo na jego koncie jest dwa razy mniej eurogąbek.

Problem z formularzami wykorzystującymi metodę POST pojawia się gdy:

  1. Odświeżamy stronę.
  2. Zapisujemy stronę do Zakładek przeglądarki internetowej.

Rozwiązanie: PRG

Wzorzec projektowy PRG polega na:

  1. Przesłaniu formularza w sposób standardowy metodą POST.
  2. Przekierowanie, a ściślej mówiąc, zwrócenie kodu 303 / 302.
  3. Zażądanie załadowania “nowej” strony z użyciem GET.

PRG i ASP.NET MVC

Jak to się powinno zrobić w ASP.NET MVC? Służy do tego: znana chyba każdemu – a niestarty często nie do końca przez wszystkich zrozumiana metoda - RedirectToAction wraz z TempData przechowujący dane pomiędzy żądaniami.

[HttpPost]
public ActionResult Edit(InputData input)
{
if (ModelState.IsValid)
{
//jakas logika...
TempData["ResultMessage"] = "Transfer eurogabek zakonczony!";
return RedirectToAction("index");
}

return View(input);
}




Tak zaimplementowana logika nie spowoduje ponownego przesłania danych przy odświeżeniu strony i to właśnie tak powinny być zaprojektowane formularze korzystające z POST.