Dzisiaj miałem przyjemność uczestniczyć w konferencji dotnetconfpl – poniżej agenda oraz małe podsumowanie tematów poruszonych w trakcie poszczególnych sesje
Dzisiaj nasze święto. Wszystkiego najlepszego z okazji 256. dnia roku – dnia programisty. Wszystkiego najlepszego – mniej błędów, więcej ciekawej i twórczej pracy oraz zadowolenia z pracy.
Do zobaczenia za tydzień na DevDay!
– Najciekawsze artykuły o .NET
Zależności pomiędzy komponentami potrafią być zmorą. Zainstaluj A zanim będziesz mógł używać B, ale B wymaga jeszcze C i D. Maskara. Ostatnio naciąłem się na problem związany z tym, że SQL Server 2005 SP2 (tak, tak :)) wymaga do działania .NET 2.0 a wszelkie próby nakłonienia go do pracy z .NET 4 kończyły się niepowodzeniem. No mówi się trudno – będziemy instalować 2.0 i idziemy dalej. Życie.
WPF i Silverlight – niby to samo a jednak mile świetlne od siebie. Przepisywanie aplikacji z jednej technologii do drugiej nawet jeśli autor piszący w tej pierwszej był świadomy ograniczeń, będzie drogą przez mękę. Jeśli nie był lub inne priorytety zaważyły, aby aplikacja WPFowa była rozwijana a później pomyśli się o SLu to jesteśmy w d… 🙂
Czasem, gdy walczymy o jak najszybszy czas odpowiedzi naszej strony musimy optymalizować jej dość dziwne elementy.
W najnowszym magazynie .Net Curry autor, Omar AL Zabir w artykule zatytułowanym “Essential it admin skills for .net developers” w jednym z punktów pokazuje jak pozbyć się dodatkowych nagłówków wysyłanych przez IIS a dodawanych czy to przez niego samego czy też ASP.NET.
Idea szczytna – każdy dodatkowy bajt kosztuje nas jakiś tam ułamek czasu zarówno po stronie serwera jak i przeglądarki. Jednakże, drogi autorze, jakby to powiedział Krzysztof Koźmic, “you are doing it wrong”. Zaprezentowany w magazynie kod:
public class RemoveASPNETStuff : IHttpModule
{
public void Init(HttpApplication app)
{
app.PostReleaseRequestState += app_PostReleaseRequestState;
}
void app_PostReleaseRequestState(object sender, EventArgs e)
{
var headers = HttpContext.Current.Response.Headers;
headers.Remove(“Server”);
headers.Remove(“X-AspNet-Version”);
headers.Remove(“ETag”);
}
}
usuwa nagłówki za pomocą dodatkowego modułu HTTP wpiętego w cały układ przetwarzający zapytania IIS. Działać działa ale da się “prościej”…
Jakie nagłówki są wysyłane
Domyślnie, nasza aplikacja MVC (4), do każdej odpowiedzi dokleja następujące nagłówki:
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Sporo tego biorąc pod uwagę, że są one całkowicie nieprzydatne :). Zobaczmy jak się możemy ich pozbyć.
X-Powered-By wystarczy usunąć z poziomu IISa:
Kolejny tj. X-AspNetMvc-Version usuniemy dodając następującą linijkę w naszym Application_Start w Global.asax
MvcHandler.DisableMvcResponseHeader = true;
Kilka bajtów mniej…:)
Trzeci odpadnie jak ustawimy atrybut enableVersionHeader=”false” na węźle httpRuntime w naszym web.configu.
Został nam już tylko Server i ETag. Ten ostatni domyślnie nie jest wysyłany a ten pierwszy? Cóż…na niego niestety nie znalazłem ładnego/prostszego rozwiązania – trzeba dodatkowym modułem 🙂
To może jednak już lepiej wszystko modułem?
Ktoś może zapytać. Skoro tak trzeba grzebać i każdy nagłówek konfigurować w innym miejscu to może jednak lepiej modułem usunąć wszystkie razem? Można, ale… minus takiego rozwiązania jest taki, że ASP.NET do naszego response’a już te nagłówki doda a dopiero później my je usuniemy. Po co ma to robić skoro od razu wiemy, że ich potrzebować nie będziemy? Lepiej wyłączyć je wcześniej – zaoszczędzimy i na ich tworzeniu i dodawaniu do obiektu odpowiedzi….
– Najciekawsze artykuły o .NET
W jednym z projektów miałem następujące zadanie do wykonania. Przekierować stare adresy na nowe. Pech chciał, że w starych adresach pojawiały się znaki ‘:’ (np. /adres/strona:2).
A potentially dangerous Request.Path value was detected from the client (:) |
Ten komunikat możemy obejść poprzez odpowiednie ustawienie parametru requestPathInvalidCharacters i usunięcie z niego dwukropka tak jak sugeruje odpowiedź na SO.
Podsumowując – dużo użerania się z IISem czy MVC gdy chce się zrobić coś z adresami co nie do końca jest wspierane. Lepiej postarać się wyperswadować klientowi taką adresację – no ale tu pozostaje kwestia tego co łatwiejsze 🙂
MiniProfiler to świetne narzędzie do debugowania działania aplikacji w MVC. Po bardzo łatwym i szybkim skonfigurowaniu pozwala na pokazanie co dzieje w bebechach naszej aplikacji, prezentując je w dość przystępnej formie jak poniżej:
http://miniprofiler.com/ |
Jak widać na załączonym powyżej obrazku, MiniProfiler ma możliwość pokazywania także zapytań SQL, które się wykonują podczas działania naszego kodu. Niestety, ale dla nHibernate’a nie działa to z automatu oraz nie ma przygotowanej odpowiedniej paczki NuGet’a (u mnie ta – MiniProfilerContrib.NHibernate – nie zadziałała). Niestety.
Choć istnieje dobry profiler dla nH – nHibernate Profiler, to jego cena, jak na polskie warunki jest dość wysoka. Dla porządku podam, że istnieje jeszcze opcja kupna licencji na miesiąc co już przekłada się na znośniejsze ceny, ale zobaczmy czy możemy zrobić coś własnymi siłami.
Pokażę, jak wykorzystując logi NHibernate’a dodać pokazywanie zapytań SQL do MiniProfiler’a.
Wystarczy w swoim kodzie dodać klasy, które ładnie zostały zaprezentowane w poniższych Gist’ach:
Ten ostatni powinien niwelować problem, z zapytaniami wsadowymi. Trzeba w nim jeszcze dodać jakiegoś log’a albo usunąć odwołania do niego. Jak już je mamy w naszym projekcie to pozostało bardzo niewiele…
Wystarczy wskazać nHibernete’owi, aby używał naszego napakowanego sterydami sterownika do SQL. Ja we Fluent robię to używając słówka Driver jak poniżej.
I gotowe…możemy cieszyć swe oczy zapytaniami do bazy robionymi przez nHibernete’a w MiniProfilderze. Yupi!
Rozwiązanie nie jest 100% działające – są przypadki, że gdzie nie gdzie poleci wyjątek. Nie daje to też takich możliwości jak wspomniany na początku profiler. Mamy tylko informacje o zapytaniach (treść, parametry i czas trwania) i ich duplikatach. nHibernate Profiler robi trochę więcej (podpowiedzi, optymalizacje, wskazuje kod, gdzie dane zapytanie jest odpalane) ale jak na moje potrzeby analizowania i wykrywania duplikatów zapytań SQL jest w zupełności wystarczające.
Miłego profilowania aplikacji!
– Najciekawsze artykuły o .NET
Najbardziej wku…rzające okienko Visual Studio? |
Jeśli nigdy nie widziałeś/widziałaś powyższego okienka modalnego (w co śmiem wątpić :)) to możesz zaliczać się do szczęśliwych osób. Okienko to, blokujące całe VS, jest chyba większą zmorą niż powolne działanie całego VS 2010 czy ślimaczenie się dialogu ‘Add Reference…’ w poprzednich wersjach.
Nie wiem co VS robi w tym czasie, ale jeśli nie pracuje nad wymyśleniem szczepionki na nieuleczalne choroby czy nie wspiera projektu SETI@Home to po prostu marnuje mój cenny 🙂 czas. Quad Core 6600, 8 GB i dysk SSD to zbyt mało 🙂 a mojej cierpliwości już braknie..
Dodatkowo, z niewiadomo jakiego powodu w SP1 zostało zmienione zachowanie okien w Visual Studio. Wcześniej można było je zostawić pod spodem innych mimo, że główne okno VS miało focus i z niego się korzystało. Teraz wszystkie okna wyskakują na górę powodując, że praca jest dużo bardziej utrudniona jeśli prócz VS trzeba mieć jeszcze jakieś inne okno na ekranie (dokument Worda ze specyfikacją, przeglądarkę z taskiem z github’a etc.). Dla mnie był to jeden z fajnych ficzerów najnowszej wersji IDE o czym wspomniałem w swoim artykule dla magazynu Programista. Jako, że później to zmieniono zaczynałem powątpiewać w swoją pamięć i zaczynałem sądzić, że się pomyliłem. Jednak testy z wersję sprzed SP1 potwierdziły, że jednak miałem rację. Uff… jeszcze nie oszalałem. Gdyby ktoś chciał to całą konwersację można znaleźć na Facebooku.
Aby post nie był przepełniony samymi gorzkimi żalami (nie lubię nieproduktywnie narzekać :]) wejdźcie teraz na Microsoft Connect i zagłosujcie za kilkoma usprawnieniami do VS. Nie będę nic sugerować – wybierzcie te, które wam najbardziej są przydatne. I oby kolejna wersja była lepsza…
– Najciekawsze artykuły o .NET
Ostatnio natrafiłem na ciekawy błąd. Dostałem raport, że nie udała się wysyłka maila w jednym z systemów. Oczywiście logowanie błędów było a gdy otworzyłem logi moim oczom ukazał się następujący błąd:
Klient lub serwer jest skonfigurowany tylko do obsługi adresów e-mail zawierających części lokalne w formacie ASCII.
Mając stacktrace zobaczyłem, że wyjątek leci przy SmtpClient.Send a dokładniej w metodzie MailAddress.GetUser. Uzbrojony w taką widzę wyruszyłem na poszukiwania.
Analiza
Długo szukać nie trzeba było, bo po kilku frazach wyskoczył dokładnie ten sam problem na stackoverflow. Niestety odpowiedzią tam jest, że .NET nie wspiera wysyłania maili z nazwą użytkownika niebędącą znakami ASCII. Przy okazji ciekawe jak autor założył konto z takimi znakami na gmail’u bo u mnie nie pozwala na wprowadzenie znaków innych niż ASCII (jak również żaden z dużych polskich ‘pocztowców’ – wp, onet, interia).
Trochę trudno mi było uwierzyć wiedząc w brak wsparcia UTF8, wiedząc że mogę w kodzie sobie napisać metodę Zażółćgęśląjaźń() i mi się skompiluje (ale proszę nie stosujcie takich nazw :]). W sieci nie spodziewałem się odnaleźć więcej informacji więc zasiadłem do VS. Odpaliłem kod gdzie ten Send był i F12…i dzięki magii R# i źródeł Framework’a ląduję w zdekompilowanej metodzie Send. Co ciekawe jednak nie widzę nigdzie ValidateUnicodeRequirement. Otwieram IlSpy’a i ładuję Framework’a – jest. Widzimy także, że flaga, która przekazywana jest do metody a ma dość znaczącą nazwę AllowUnicode jest ustawiana na podstawie wyniku innej funkcji – bool allowUnicode = this.IsUnicodeSupported()
private bool IsUnicodeSupported()
{
if (this.DeliveryMethod == SmtpDeliveryMethod.Network)
{
return this.ServerSupportsEai && this.DeliveryFormat == SmtpDeliveryFormat.International;
}
return this.DeliveryFormat == SmtpDeliveryFormat.International;
}
Widzimy zatem, że aby nasz mail z utfową nazwą do odbiorcy dotarł (zakładamy, że wysyłamy przez sieć – SmtpDeliveryMethod.Network) – musimy spełnić dwa warunki. Mieć ustawiony DeliveryFormat na International oraz flaga ServerSupportsEai musi zwrócić true. Zobaczmy co się za tym kryje. Kilka przejść w ILSpy’u, kilka użyć Analyze tu i tam i mamy, że tak na prawdę interesuje nas pole serverSupportsEai na klasie SmtpPooledStream. Jeszcze kilka użyć Analyze i lądujemy w metodzie ParseExtensions. W niej to prawie pod sam koniec ustawiane jest to pole na true.
if (string.Compare(text, 0, “SMTPUTF8”, 0, 8, StringComparison.OrdinalIgnoreCase) == 0)
{
((SmtpPooledStream)this.pooledStream).serverSupportsEai = true;
}
Mając ten fragment kodu lądujemy na odpowiednim wpisie na Wikipedii gdzie możemy co nieco na ten temat przeczytać.
Podsumowując
Wygląda na to, że .NET potrafi obsłużyć UTF8 w adresach e-mail, ale muszą być spełnione dodatkowe warunki. Odpowiednio ustawiona flaga DeliveryFormat oraz serwer, który wspiera rozszerzenie SMTPUTF8, a te jak widzimy we wpisie na Wikipedii popularne nie są 🙂
Chętnie bym moje rozważania teoretyczne sprawdził w praktyce i odpowiednio skomentował pytanie na SO. Gdyby ktoś wiedział, gdzie można założyć skrzynkę z nazwą lokalną w UTF8 – dajcie znać w komentarzu.
– Najciekawsze artykuły o .NET
Jeśli uważasz, że masz w swoim systemie duże tabele – think again! Poniżej zrzut (zaciemniony, niestety) z jednego z systemów…niedaleko obok w pliku edmx leży sobie druga podobna tabelka…
– Najciekawsze artykuły o .NET