Urlop ojcowski to nie tylko gry i zabawy. Większość tego wspaniałego czasu spędza się uspokajaniu bobasa oraz próbach poradzenia sobie z ciekawymi sytuacjami, jak np. wybuchowe kupki. Uwierzcie, że określenie tego mianem wybuchu jest jak najbardziej odpowiednie. I wiem, że nie takiego zdjęcia mogliście się spodziewać po technicznym wpisie na programistycznym blogu, ale chyba dacie sobie radę. ;)
Co?! JUŻ czas na RC? Chyba musisz mi zmienić pampersa…
Podczas mojej nieobecności, team ASP.NET MVC kontynuował ciężką robotę i jest już gotów, aby ogłosić wersję RC dla ASP.NET MVC 2. Wypróbuj ją!
ASP.NET MVC 2 Release Candidate
Jak zwykle, w release notes znajdziecie opis wprowadzonych zmian. I cierpliwie czekajcie, bo, jak się spodziewam, niedługo ujrzymy kolejny, epicki wręcz post Scott’a na temat tego wydania MVC.
Szczegóły
Jak można się spodziewać po release candidate, największy nacisk położyliśmy na naprawę błędów i ulepszenie istniejących feature’ów. Spędziliśmy też sporo czasu nad optymalizacją kodu ASP.NET MVC pod kątem szybkości wykonywania.
Skoncentrowaliśmy się też na walidacji po stronie klienta. Między innymi skrypt walidacji został przesunięty do osobnego pliku, i może być teraz deklarowany zarówno na górze, jak i na dole strony. Można teraz również lokalizować skrypty walidacji.
Następną zmianą związaną z walidacją jest pojawienie się przeładowanych wersji ValidationSummary, który pozwalają na wyświetlenie błędów na poziomie modelu. Może się to przydać w sytuacji, kiedy błędy walidacji wyświetlane są zaraz obok pól (domyślnie). Błędy zostałyby wtedy powielone w ValidationSummary, jednak teraz można tam wyświetlić ogólne podsumowanie (np. “Wystąpił błąd zgłoszenie.”), jak również listę błędów, które nie są powiązane z konkretnym polem.
Co dalej?
Oczywiście RTM! Będzie on zawarty w wersji RTM Visual Studio 2010, która jest zaplanowana na marzec. Prawdopodobnie wersja VS2008 dostanie swój release ASP.NET MVC 2 trochę wcześniej. Cały czas nad tym pracujemy.
Translation of original post by Phil Haack: / Tłumaczenie oryginalnego posta napisanego przez Phil’a Haack’a:
ASP.NET MVC 2 RC Released
Artykuł z serii “W dżungli Codeplex”
Projekt: ASP.NET MVC Starter Kit
Strona domowa projektu: http://mvcmembership.codeplex.com/
Typ projektu: Biblioteki + kod źródłowy do bezpośredniego użycia + kod widoków
Status projektu: Stable – 07.08.2009, następny release przewidywany dla ASP.NET MVC 2.0 (Preview 1/2)
Zakres projektu: kontrolek i widoki w postaci platformy do zarządzania użytkownikami MembershipProvider i RoleProvider
Platforma: ASP.NET MVC 1.0, ASP.NET MVC 2.0
Docelowe użycie: projekty ASP.NET MVC wymagające kontrolera do zarządzania użytkownikami.
Docelowa grupa odbiorców (subiektywnie): początkujący developerzy ASP.NET MVC; developerzy, którzy nie posiadają własnego, reużywalnego kodu do zarządzania MembershipProvider i RoleProvider w ASP.NET MVC.
Łatwość implementacji: Łatwa.
Typ implementacji: dołączenie bilbiotek do projektu (reference), wklejenie kodu źródłowego do projektu, modyfikacja global.asax, wklejenie plików widoków do projektu.
Ocena: 7/10
Zalety:
- Łatwa implementacja
- Możliwość użycia out-of-box
- Pełna funkcjonalność MembershipProvider i RoleProvider
- Łatwa modyfikacja do swoich potrzeb
- Proste użycie do IoC (najlepiej kontener z domyślną iniekcją w konstruktorze, np. Unity)
Wady:
- Projekt nie używa MvcContrib (np. PagedList w osobnej bilbliotece)
- Kod nie jest kompatybilny z narzędziem StyleCop (dodatkowo do wyrównywania kodu używa tabulatorów zamiast spacji)
- Tylko własny build – nie ma wersji projektu już skompilowanego
Inne:
- Prosty projekt – dla własnych zastosowań lepiej do przystosować
- Zawiera tak małą ilość kodu, że powinien być tylko częścią MvcContrib
Opis:
Dobre uzupełnienie projektów pisanych w ASP.NET MVC. Jest to właściwie pewien zbiór kodu, który powinien być w rękawie każdego developera tworzącego w tej technologii. Warto ten kod przystosować do własnych potrzeb, bo w wersji out-of-box nawet jeśli nie wywrze na kliencie złego wrażenia, to będzie świadczyć o naszej, dość niskiej w takim przypadku, klasie. Mam nadzieję, że w przyszłości ten projekt razem z, chociażby xVal, znajdzie się w MvcContrib, albo w projektach Castle, by były jakoś ustandaryzowane i dobrze ze sobą współpracowały.
Jeśli jednak jesteś developerem (np. freelancerem), który posiada już swój kod tego typu, to ten projekt raczej Ci się nie przyda. Możesz co najwyżej zaglądnąć do WebsiteSample – jest w release na stronie głównej projektu – i porównać ze swoim kodem. Ale nie trać na to zbyt wiele czasu.
Jestem programistą .Net. I jestem programistą wygodnym. Lubię poświęcać czas na szukanie narzędzi, które w przyszłości pozwolą mi oszczędzić czas. No i najważniejszym pytaniem jest oczywiście – czy to jest opłacalne? Czy więcej czasu zaoszczędzę używając tych narzędzi/projektów/przydatnych kodów źródłowych, niż stracę na ich wyszukiwanie? Do tego trzeba też doliczyć obciążenie spowodowane przystosowaniem do nowych technologii i poświęcenie jednego projektu na pastwę losu (bo zawsze może się nie udać wykorzystanie jakiejś technologii).
Z tego typu projektów bardzo spodobało mi się .Net Ria Services. Jest to wspaniałe narzędzie rozwijane przez Microsoft, a służy do tworzenia warstwy biznesowej i proxy do Linq2Sql/Entity Framework dla Silverlight/Wpf/itd. Przystosowanie do tych narzędzi zajmuje naprawdę niewiele czasu, a ich użycie jest bardzo proste. Wielką serię na ich temat stworzył na swoim blogu Brad Abrams (6 sierpnia pojawiła się 20. część!). Wada: wciąż CTP, a RTM jeśli się nie mylę, dopiero w .Net 4.0.
A w tej serii chciałbym się skupić na tym, co tworzy społeczność. Bo często widziałem na Codeplex ciekawe projekty, ale były one niepopularne, miały słabe statystyki, i chyba czekały na to, że ktoś je zauważy, rosły sobie powoli w cieniach takich gigantów Codeplex jak: DotNetNuke, Ajax Control Toolkit, czy (w życiu z tego nie korzystałem, ale jak widać wielu .netowców gra w WoWa) Rawr. Mówiłem wtedy do siebie: “Mhm, wygląda ciekawie. Na pewno użyję tego w następnym projekcie.”, ale niestety z braku czasu najczęściej o nich zapominałem, a kolejne projekty wykonywałem cały czas tak samo. Przyszedł jednak taki czas, że należy się tym problemem zająć i zacząć magazynować tego typu aplikacje dla siebie (i jak mam nadzieję, również dla innych), a właściwie to bardziej je katalogować.
Aby taki katalog był użyteczny, planuję stworzyć dla niego osobną kategorię w blogu, ewentualnie dodatkowo może to będą również zagnieżdżone kategorie dla różnych typów projektów – ASP.NET (MVC), Wpf, Silverlight, itd. Niestety wiąże się z tym brak możliwości wyszukiwania potrzebnych aplikacji, tak jak na Codeplex, ale niestety taki już los amatorskiego katalogu – plus jest taki, że można być miło zaskoczonym, iż istnieje taki projekt, który może nam niesamowicie pomóc. ;] Każda aplikacja będzie przetestowana, opisana i oceniona – w sposób praktyczny , będziesz więc wiedzieć, czy warto użyć już teraz, ile czasu potrzeba na przyuczenie się do jej użycia oraz oczywiście pokazany będzie poglądowy fragment kodu – użycia takich bibliotek, bądź kod źródłowy samych bibliotek.
Podstawą mojego działania jest powiedzenie, że nie warto odkrywać koła – po co więc pisać kod, który został przez kogoś już napisany (oby to tylko się obróciło przeciwko mnie, jeśli jest już ktoś, kto opisuje wyszukane na Codeplex aplikacje, to daj mi znać ;). Zapraszam więc do czytania serii – RSS bloga jest perfekcyjnie ukryty w skinie, który sobie wybrałem. Jednak możesz być jedną z tych nielicznych osób, którym uda się go odnaleźć na samym dole prawej kolumny.
PS. Jeśli chciałbyś, żebym w swoim katalogu zamieścił jakąś aplikację, którą udało Ci się znaleźć, to pisz do mnie przez kontakt na blogu. Tak samo, jeśli nie wiesz, co to jest za projekt, a nie masz czasu go przetestować – postaram się dla Ciebie znaleźć trochę czasu – i to zrobić (na razie tyko projekty ASP.NET, MVC oraz Silverlight).
Ogłoszenia techniczne dotyczące wszystkich następnych postów:
uwagi w tekście, których nie ma w oryginale, oznaczone są kwadratowymi nawiasami [ ];
tłumaczenia obowiązuje disclaimer.
Translation of original post by Phil Haack: / Tłumaczenie oryginalnego posta napisanego przez Phil’a Haack’a: http://haacked.com/archive/2009/08/04/default-templated-views.aspx
Uwaga! Ten post został napisany na podstawie ASP.NET MVC 2.0 Preview 1, a więc w przyszłości mogą się zmienić pewne szczegóły implementacyjne. Wkrótce spróbuję wrócić do ASP.NET MVC 1.0. :)
Wczoraj na spotkaniu z “The Gu” poruszliśmy kwestię automatycznych widoków. Wyobraź sobie, że możesz utworzyć jakiś obiekt modelu w akcji w kontrolerze, przekazać go do widoku, a ASP.NET MVC wygeneruje dla Ciebie ze schematu stronę do edycji lub przeglądania danych.
Właśnie wtedy świecąca żaróweczka pojawiła się nad głową Scott’a i nagle wspomniał on o pomyśle na realizację tego planu. Jego idea bardzo mi się spodobała i zdecydowałem, że dziś w nocy spróbuje zrealizować jego prototyp. Jednak zanim pokaże Ci ten prototyp, pozwól że wspomnę nieco o podłożu tego pomysłu.
Jednym z genialnych feature’ów ASP.NET MVC jest możliwość użycia widoków znajdujących się w folderze ~/Views/Shared dla wszystkich kontrolerów. Na przykład, załóżmy że chciałbyś stworzyć domyślny widok akcji nazwanej Index dla wszystkich kontrolerów. Możesz więc po prostu dodać widok Index do folderu Shared.
Tak więc każdy kontroler z akcją Index automatycznie użyje tego widoku, chyba że widok Index będzie się znajdował w folderze tego kontrolera.
Wobec tego, może moglibyśmy z tego skorzystać budując proste strony CRUD (Create, Read, Update, Delete). A jeśli umieścilibyśmy domyślne widoki o odpowiednich nazwach w folderze Shared? Co moglibyśmy umieścić w tych widokach? Cóż, więc oczywiście skorzystalibyśmy w nich z Templated Heades! [wspomniane też tutaj] W ten sposób dodając nowe akcje o nazwach zgodnych z konwencją widok byłby od razu gotowy – bez potrzeby tworzenia kolejnego widoku.
Stworzyłem dziś prototyp realizujący ten pomysł. Najpierw dodałem trzy widoki do folderu Shared – Details, Edit i Create.
Spójrzmy no widok Details, zobaczyć jak proste to jest to rozwiązanie.
<%@ Page Inherits="System.Web.Mvc.ViewPage"%>
<asp:Content ContentPlaceHolderID="TitleContent" runat="server">
Details for <%= Html.Encode(ViewData.Eval("Title")) %>
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<fieldset class="default-view">
<legend><%= Html.Encode(ViewData.Eval("Title")) %></legend>
<% ViewData["__MyModel"] = Model; %>
<%= Html.Display("__MyModel") %>
</fieldset>
</asp:Content>
Widzimy tutaj niegeneryczną wersję ViewPage. Ponieważ ten widok może zostać użyty przez wiele kontrolerów, nie wiemy jaki typ modelu zostanie tutaj użyty (aż do momentu runtime’u oczywiście), nie możemy użyć silnie typowanego widoku, możemy jednak użyć niegenerycznego helper’a Html.Display, aby wyświetlić model.
Dziwną rzecz, którą tu zauważysz, jest pewne oszustwo, którym musiałem się posłużyć. Dodałem obiekt modelu jako zwykły klucz do ViewData, a to ponieważ a Preview 1 znajduje się bug, który powoduje, że Html.Display(“”) nie używa ViewData.Model. Jestem jednak pewien, że zostanie to poprawione w przyszyłych release’ach.
Html.DisplayFor(m => m) również tutaj nie zadziała, ponieważ jako metoda generyczna opiera się o typ zadeklarowany (a nie runtime’u), a więc w tym przypadku będzie to Object.
Mając te widoki posiadamy już podstawowy CRUD (a właściwie Create, Edit i Details). Następnym razem tworząc nową akcję nazwaną tak jak te schematy, nie będę musiał tworzyć widoku.
Sprawdźmy to rozwiązanie w akcji. Kocham NerdDinner, ale jednak wolałbym tym razem użyć innego modelu. Wypróbujmy więc wojowników Ninja!
Najpierw stwórzmy prostą klasę Ninja.
public class Ninja
{
public string Name { get; set; }
public int ShurikenCount { get; set; }
public int BlowgunDartCount { get; set; }
public string Clan { get; set; }
}
Następnie utwórzmy NinjaController używając Add Controller z menu kontekstowego folderu Controllers.

Następnie otworzy nam się okienko, w którym można wybrać nazwę dla kontrolera i zaznaczyć opcję wygenerowania akcji ze schematu (który oczywiście można w pełni dostosować).

Wewnątrz nowego kontrolera stworzyłem przykładowego Ninja (jako statyczną klasę dla celów demonstracji) i zwracam ją jako model w akcji Details.
static Ninja _ninja = new Ninja {
Name = "Ask a Ninja",
Clan = "Yokoyama",
BlowgunDartCount = 23,
ShurikenCount = 42 };
public ActionResult Details(int id)
{
ViewData["Title"] = "A Very Cool Ninja";
return View(_ninja);
}
Zauważ, że umieściłem też wewnątrz ViewData tytuł (Title), bo wiem że widok go wyświetli. Mógłbym w rzeczywistości stworzyć NinjaViewModel zamiast osobno dodawać Title do ViewData, ale ze względu na fakt, że jest to tylko demonstracja – nie zrobiłem tego.
Kiedy otworzymy widok Details kontrolera Ninja, zobaczymy:
Dzięki domyślnym schematom, mogę zapomnieć o tworzeniu widoku i skupić się na tworzeniu metod akcji. Widok zostanie automatycznie utworzony.
Jeśli będę potrzebować drobnych zmian zawsze mogę oznaczyć klasy/właściwości atrybutami DataAnnotation, tutaj zmienię nazwy wyświetlanych właściwości.
public class Ninja
{
public string Name { get; set; }
[DisplayName("Shurikens")]
public int ShurikenCount { get; set; }
[DisplayName("Blowgun Darts")]
public int BlowgunDartCount { get; set; }
public string Clan { get; set; }
}
Jeśli zaniepokoiło Cię to, że obarczam model zadaniami należącymi do warstwy prezentacji, to uznajmy, że ten model został stworzony na potrzeby widoku. Dodatkowo w przyszłości zamierzamy dostarczyć rozwiązania, które pomogą przechowywać te ustawienia meta-data w innym miejscu. [oczywiście chodzi o definiowanie meta-data w runtime]
Kiedy zrekompiluję i odświeżę stronę, labele będą zawierać odpowiednie nazwy.
Alternatywnie mogę utworzyć nowy schemat wyświetlania dla Ninja. Wszystko, co muszę zrobić, to dodać folder DisplayTemplates do folderu Shared, a następnie utworzyć schemat dla typu Ninja.
Następnie w menu kontekstowym folderu wybieram Add View, zaznaczam opcję silnie-typowanego widoku i wybieram odpowiedni typ – wiem przecież, że template tworzę dla klasy Ninja.
Po dodaniu widoku, powinienem zobaczyć template w folderze DisplayTemplate. Mogę też otworzyć go do edycji i wprowadzić bardziej rozbudowane zmiany.
Po rekompilacji i odświeżeniu strony zobaczę:
Ostatecznie, jeśli potrzebuję jeszcze większej kontroli nad widokiem, mogę dodać widok Details do folderu widoków kontrolera Ninja, który da mi już całkowitą kontrolę i zakryje domyślny widok Details z folderu Shared.
Tak na ten moment wygląda realizacja pomysłu, który nazywam “domyślnymi schematami widoków” (“default templated views”). Pokazałem Ci pomysł, ale również sposób na wcielenie go do swoich aplikacji. Jak widzisz – możesz go z łatwością użyć, a nawet zmodyfikować, tak aby odpowiadał Twoim potrzebom.
Kiedy Scott o tym mówił, stwierdził nawet: “Czemu o tym wcześniej nie pomyślałem, przecież to oczywiste.” (albo coś w tym stylu, nie zapisałem tego).
A ja myślałem dokładnie tak samo, dopóki nie uświadomiłem sobie, że wcześniej nie mieliśmy takich helper’ów, więc domyślne schematy widoków nie miałyby sensu w ASP.NET MVC 1.0.
Ale w ASP.NET MVC 2.0 Preview 1 mamy takie helper’y, a ten post pokazuje pewne środki do budowania generowanych widoków w Twoich aplikacjach.
I zanim zapomnę, tutaj możesz pobrać mój przykładowy projekt Ninja.
Translation of original post by Scott Guthrie: / Tłumaczenie oryginalnego posta napisanego przez Scott’a Guthrie: http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx
Zespół ASP.NET właśnie opublikował pierwszy preview nowej wersji ASP.NET MVC – MVC Version 2. Możesz pobrać go tutaj.
Preview 1 działa w środowisku .NET 3.5 SP1 i VS 2008, i może być zainstalowane równolegle z ASP.NET MVC 1.0 (co oznacza, iż nie pojawi się między nimi konflikt, a dotąd działające aplikacje ASP.NET MVC 1.0 nie zostaną uszkodzone jeśli zainstalujesz nowe preview). Gdy zainstalujesz zarówno ASP.NET MVC 1.0, jak i ASP.NET MVC 2.0, w oknie dialogowym nowego projektu Visual Studio 2008, będziesz miał do wyboru dwa projekty ASP.NET MVC:
W release notes, które znajdziesz w ASP.NET MVC 2 Preview, opisane jest, co należy zrobić, aby upgrade’ować aplikacje ASP.NET MVC 1.0, by już móc używać nowych możliwości MVC 2.0.
Nowe funkcje
ASP.NET MVC 2.0 zawierać będzie sporo nowych funkcji i możliwości (część z nich już znajduje się na roadmap’ie ASP.NET MVC). Preview 1 daje nam możliwość ogólnego spojrzenia na część nowych funkcji. A jeszcze więcej z nich pojawi się w przyszłych, kolejnych wersjach preview. Preview 1 jest jednak wciąż wersją bardzo wczesną – zespół ASP.NET opublikował tą wersję, by uzyskać od społeczności ocenę planów rozwoju ASP.NET MVC oraz nowe pomysły na rozwój.
Poniżej znajdziesz detale kilku nowych możliwości Preview 1:
Wsparcie dla Obszarów
ASP.NET MVC 2.0 zawiera wsparcie dla nowej funkcji zwanej “obszary”, która umożliwia łatwiejsze dzielenie i grupowanie funkcjonalności w aplikacjach MVC.
Obszary pozwalają na grupowanie kontrolerów i widoków, by podzielić duże aplikacje na pewnego rodzaju sekcje, co pozwala je izolować. Każdy obszar może być zaimplementowany jako osobny projekt ASP.NET MVC, który może być powiązany z główną aplikacją. Pomaga to radzić sobie ze złożonością dużych aplikacji i ułatwia współpracę kilku różnych zespołów pracujących razem nad jedną aplikacją.
Poniżej widać screen, który pokazuje jedną solucję, która zawiera trzy projekty. Jeden z nich nazywa się “CompanySite” i zawiera główną treść portalu, layout,kontrolery i widoki. Następnie są dwa projekty obszarów – “Blogs” i “Forums”. Te projekty zawierają funkcjonalność dostępną pod URL’ami /Blogs i /Forums – mają własne kontrolery, widoki i własne ustawienia routingu:
Preview 1 zawiera wstępną implementację idei obszarów. Nie zawiera jednak jeszcze żadnego wsparcia w postaci narzędzi (na ten moment musisz ręcznie dodać build task, by utworzyć projekt obszaru i odpowiednio go ustawić). Przyszłe preview będą zawierać odpowiednie wsparcie narzędziowe i rozszerzą możliwości obszarów.
[Idea obszarów w aplikacjach ASP.NET MVC pojawiła się już stosunkowo dawno, lecz nie przyjęła tak rozbudowanej formy w sensie technicznym - http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx – przyp. tłum.]
DataAnnotation Validation Support
ASP.NET MVC 2.0 zawiera teraz wbudowane wsparcie dla walidacji DataAnnotation, które pojawiło się w .NET 3.5 SP1 – i które jest teraz używane w ASP.NET Dynamic Data i .NET RIA Services. DataAnnotations umożliwia łatwe, deklaratywne utworzenie walidacji dla klas Model i ViewModel w obrębie aplikacji, oraz automatyczny binding i wsparcie UI helper dla walidacji w ASP.NET MVC.
Aby zobaczyć tą funkcję w akcji, możemy stworzyć nową klasę ViewModel o nazwie “Customer” (deklaracja poniżej), która ma 5 właściwości (zaimplementowane jako auto-properties).
Teraz możemy oznaczyć właściwości odpowiednimi atrybutami (System.ComponentModel.DataAnnotations namespace), by ustawić reguły walidacji. Koid poniżej pokazuje użycie 4 różnych reguł - [Required], [StringLength], [Range] i [RegularExpression]. W DataAnnotations znajdziesz też bazową klasę (ValidationAttribute), dzięki której możesz zbudować własne reguły walidacji.

Teraz utworzymy kontroler CustomersController, który będzie posiadać dwie akcje Create. Pierwsza z nich będzie obsługiwać żądania GET przychodzące na adres “/Customers/Create”, i renderować widok operty o pusty obiekt Customer. Druga akcja Create będzie obsługiwać żądania POST na ten sam adres URL (oraz będzie pobierać obiekt klasy Customer jako parametr). Jej zadaniem będzie wykonanie walidacji obiektu Customer, a następnie: powtórne wyświetlenie widoku z użyciem wprowadzonych danych – jeśli dane nie spełniają kryteriów walidacji, bądź wyświetlenie widoku o nazwie “Success” - jeśli dane spełnią kryteria.
Na końcu możemy kliknąć prawym przyciskiem myszy (PM) na jedną z tych akcji, wybrać “Add View” z menu kontekstowego i automatycznie wygenerować widok “create” ze schematu, oczywiście na podstawie klasy Customer. Kiedy to zrobimy, wygenerowany widok będzie zawierać (jak poniżej) tag <form> dla naszej klasy Customer:
Teraz, gdy przejdziemy do adresu “/Customers/Create” w przeglądarce, zobaczymy pusty formularz:
Jeśli wprowadzimy niepoprawne dane i wyślemy je do serwera, model binder odnajdzie atrybuty DataAnnotations, i automatycznie przeprowadzi walidacje w oparciu o zadeklarowane przez nas reguły. właśnie w przypadku tych niepoprawnych danych akcja zwróci ten sam widok jeszcze raz, tym razem jednak będzie on zawierał wprowadzone przez nas dane oraz wiadomość o tym, że błędnie je wprowadziliśmy. Zauważ, że informacje o błędnych danych zostały wyświetlone całkowicie automatycznie – nie trzeba było do tego żadnego dodatkowego kodu.
Powyższy formularz zostanie wyświetlony za każdym razem, kiedy wprowadzone zostaną błędne dane i zostaną one przesłane do serwera.
W przyszłych preview ASP.NET MVC 2.0 zamierzamy wprowadzić jQuery Validation plugin jako część domyślnego schematu projektu, i dodać również wsparcie dla automatycznej walidacji JavaScript po stronie klienta. To umożliwi developerom łatwe tworzenie walidacji w jednym miejscu – może to być Model lub ViewModel, oraz zastosowanie tej walidacji w dowolnym miejscu aplikacji.
Jeśli nie chcesz oznaczać atrybutami klas Modelu lub ViewModelu bezpośrednio, możesz utworzyć klasę-kumpla (“buddy class”), która będzie enkapsulować reguły walidacji. Jest to również bardzo przydatne w scenariuszach takich jak np. auto-generowanie kodu w VS (np. diagramy LinqToSql, EF).
Oprócz wbudowanego wsparcia dla DataAnnotations, DefaultModelBinder w ASP.NET MVC 2.0 ma teraz nowe wirtualne metody, dzięki czemu możemy go zintegrować z innymi frameworkami do walidacji (np. Castle Validator, EntLib Validation, itd.). Metody UI helper’ów odpowiedzialne za walidację, stworzone są do współpracy z dowolnymi frameworkami – nie są świadome użycia DataAnnotations).
Silnie typowane UI helper’y
ASP.NET MVC 2.0 zawiera nowe HTML UI helper’y, które umożliwiają użycie silnie typomanych wyrażeń lambda podczas odwołania do Modelu. Umożliwia to łatwiejsze sprawdzanie widoku podczas kompilacji (w związku z czym bugi zostaną znalezione już podczas kompilacji, a nie podczas działania aplikacji), jak również umożliwia lepsze wsparcie Intellisense podczas tworzenia widoku.
Poniżej możesz zobaczyć usprawnienie Intellisense w akcji – zauważ w jaki sposób otrzymałem pełną listę właściwości Modelu, używając nowej metody UI helpera - Html.EditorFor():
Preview 1 ma wbudowane wsparcie dla nowych helperów Html.EditorFor(), Html.LabelFor() i Html.DisplayFor(). Nowe binaria MVC Futures, które opublikowaliśmy w tym tygodniu dodają również Html.TextBoxFor(), Html.TextAreaFor(), Html.DropDownListFor(), Html.HiddenFor() i Html.ValidationMesssageFor() (z czasem zostaną one przesunięte do głównej biblioteki ASP.NET MVC 2.0).
Poniżej możesz zobaczyć nową wersję widoku “Create” utworzoną z użyciem tych nowych helperów. Zamiast klasycznych helperów użyliśmy silnie typowanych wyrażeń lambda. Dzięki temu mamy pełne wsparcie Intellisense, jak również sprawdzanie widoku podczas kompilacji.
Helper Html.LabelFor() powyżej generuje HTML w postaci <label for=”Name”>Name:</label>.
Helper Html.EditorFor() może być użyty do dowolnego typu danych. Domyślnie jest on sprytny i generuje odpowiedni tag HTML <input/> w zależności od typu danych. Na przykład, dla pierwszych czterech właściwości powyżej (łańcuchy znaków i integery) wygenerowany zostanie tag <input type=”text”/>, natomiast dla ostatniej właściwości (wartość bool) wygenerowany zostanie tag <input type=”checkbox”/>.
Html.EditorFor() ma jeszcze jedną ciekawą cechę – można też przekazać mu złożony obiekt. Domyślnie w takiej sytuacji dla każdej publicznej właściwości zostanie wtedy wygenerowany odpowiedni tag <label>, <input> oraz, jeżeli taki istnieje – komunikat walidacji. Możemy więc przepisać powyższy widok i wywołać Html.EditorFor() tylko raz – na obiekcie Customer, a wynikowy HTML będzie taki sam:
Silnie typowane helpery pozwalają też na oznaczenie właściwości ViewModel atrybutami [DisplayName], które pozwalają na zmianę nazwy wyświetlanej w tagu <label/> (tak więc na przykład: zamiast domyślnej nazwy “IsActive”, możemy ją zmienić - [DisplayName(“Is Active Customer:”)]).
Zadziała tutaj również atrybut [ScaffoldColumn(false)] – który spowoduje ukrycie właściwości, którą nim oznaczymy, oczywiście tylko, kiedy złożony obiekt analizować będzie Html.EditorFor().
[Tych samych atrybutów używamy w Dynamic Data – muszę więc przyznać, że w przyszłości może to dać ciekawe rezultaty – przyp. tłum.]
Wsparcie dla UI Helper Templating
Html.EditorFor() i Html.DisplayFor() obsługują zarówno proste typy, jak i złożone, z wieloma właściwościami, można by rzecz out-of-the-box. Jak wspomniałem wyżej, można to również nieco modyfikować za pomocą odpowiednich atrybutów.
Często jednak programiści chcą edytować wynikowy HTML w sposób bardziej niekonwencjonalny lub mieć nad nim całkowitą kontrolę. Html.EditorFor() i Html.DisplayFor umożliwiająto za pomocą mechanizmu schematów/templates. Schematy definiowane są w takim przypadku w kontekście danego typu (typu prostego, bądź klasy).
W Preview 1 można dodać opcjonalne foldery “EditorTemplates” i “DisplayTemplates” dla konkretnego kontrolera wewnątrz \Views\[nazwaKontrolera], bądź dla całej aplikacji wewnątrz \Views\Shared.
Następnie można dodać do tych folderów kontrolki ASP.NET, które będą służyć do zmieniania sposobu renderowania wybranych typów. Na przykład poniżej dodałem folder EditorTemplates do folderu \Views\Shared i dodałem do niego 3 kontrolki:
Schemat “Customer.ascx” który widzisz powyżej, zostanie użyty zawsze, kiedy wywołam Html.EditorFor() i jako parametr użyję obiekt typu “Customer” (np. mogę tu ustawić całkowicie dowolny layout dla różnych właściwości tej klasy). “DateTime.ascx” zostanie użyty dla właściwości typu DateTime (np. mogę tutaj ustawić JavaScript’owy datepicker dla pola <input/>). Ewentualnie mógłbym dodać kontrolkę “Object.ascx”, która zmieniłaby domyślny sposób renderowania dla wszystkich obiektów.
Dodatkowo można też użyć “named templates” do zmieniania wyglądu konkretnych właściwości. Standardowym scenariuszem w tym przypadku jest “CountryDropDownList”, który obsługuje właściwość typu string, ale zamiast zwykłego textbox’a, używa <select> z listą wyboru, z której użytkownik może wybrać jakąś wartość. Poniżej widzisz, jak mógłby wyglądać taki schemat:
Możemy wyszukać odpowiedni schemat podając nazwę jako parametr przy wywołaniu Html.EditorFor(). Na przykład, poniżej oprócz wyrażenia podającego odpowiednią właściwość, określamy również nazwę schematu, którą chcemy użyć:
Ewentualnie, możemy oznaczyć atrybutem [UIHint] właściwości we ViewModel. Pozwoli to na określenie nazwy schematu w jednym miejscu, dla wszystkich miejsc (oznaczasz atrybutem typ/właściwość, a we wszystkich miejscach w aplikacji użyty jest podany schemat). Poniżej znajduje się przykład użycia atrybutu [UIHint] dla właściwości Customer.Country – dzięki temu podczas renderowania zostanie użyty schemat “CountryDropDown.ascx”:
Kiedy oznaczymy typ/właściwość tym atrybutem, nie musimy już wpisywać nazwy schematu przy wywoływaniu Html.EditorFor(). A kiedy odświeżymy stronę /Customers/Create, właściwość Country zostanie przedstawiona w postaci dropdownL zamiast textbox’a:
Inne super dodatki
ASP.NET MVC 2.0 zawiera też masę małych, ciekawych ułatwień. Oto kilka moich ulubionych:
Nowy atrybut [HttpPost]
Dość często w ASP.NET MVC rozdzielamy obsługę żądań na dwie akcje: jedną obsługujemy GET, a drugą POST.
W ASP.NET MVC 1.0 używasz zapewne atrybutu [AcceptVerbs(HttpVerbs.Post)], by oznaczyć, że akcja obsługuje POST.
Oczywiście, wciąż działa to w ASP.NET MVC 2. Alternatywnie jednak, możesz użyć nowszego atrybutu [HttpPost], który działa w ten sam sposób:
[W MvcContrib ten atrybut to [AcceptPost] – przyp. tłum.]
Domyślne wartości parametrów
Obsługa opcjonalnych parametrów to częsty scenariusz. W ASP.NET MVC 1.0 zapewne rozwiązałbyś to, przez zarejestrowanie odpowiednich zasad routingu i wpisanie tam domyślnych wartości albo przez oznaczenie parametrów jako nullable i odpowiednie obsłużenie ich w kodzie.
ASP.NET MVC 2.0 Preview 1 wspiera teraz domyślne wartości parametrów poprzez atrybut DefaultValueAttribute z System.ComponentModel namespace. Pozwala to na podanie wartości, którą ASP.NET MVC ma zwrócić, jeśli nie została podana w żądaniu. Na przykład poniżej widać jak możemy obsłużyć zarówno /Products/Browse/Beverages, jak i /Products/Browse/Beverages?page=2, w pierwszym przypadku automatycznie dostaniemy wartość “1”, bo nie jest ona określona w querystring:
VB pozwala już dziś na określenie domyślnej wartości bez użycia atrybutu [DefaultValue] jak powyżej, a C# będzie tę funkcję posiadał w .NET 4.0:
To znacznie ułatwi tego typu scenariusze.
Binding danych binarnych
ASP.NET MVC 2.0 Preview 1 dodaje też wsparcie dla bindingu łancuchów zakodowanych jako base64 do byte[] lub System.Data.Linq.Binary. Teraz mamy dwie przeciążone wersje Html.Hidden(), które mogą użyć danych tego typu. Są one bardzo użyteczne np. w celu umożliwienia concurrency control w aplikacji poprzez przechowywanie w tego typu polu wartości timestamp.
Podsumowanie
Kliknij tutaj, aby pobrać archiwum “.zip”, które zawiera projekt ASP.NET MVC 2.0 z kodem, który tutaj przedstawiłem.
Dzisiejszy build ASP.NET MVC 2.0 to jedynie preview. Kolejne feature’y będą się z czasem pojawiać w kolejnych preview, a zespół ASP.NET czeka na Twoje opinie i pomysły, co można zmienić lub poprawić.
Celem regularnych wersji preview jest wspólne budowanie ASP.NET MVC tak, aby odpowiadał potrzebom społeczności. Wszelkie sugestie, pytania lub opinie możesz wysłać na forum ASP.NET MVC. Więcej o tym release’ie możesz się dowiedzieć z posta Phila Haacka na ten temat lub z video na Channel9.
Scott
P.S. Śledź mnie na portalu Twitter tam często wysyłam mini-posty i publikuje ciekawe linki. Mój Twitter : http://www.twitter.com/scottgu. A nazwa mojego konta to: @scottgu.

Translation of original post by Scott Guthrie: / Tłumaczenie oryginalnego posta napisanego przez Scott’a Guthrie: http://weblogs.asp.net/scottgu/archive/2009/06/02/microsoft-web-platform-installer.aspx
Jedną z najciekawszych aplikacji wychodzących w tym roku jest mały menadżer pobierania – Microsoft Web Platform Installer – ułatwia on instalowanie i konfigurowanie serwera i różnych aplikacji bądź modułów używanych przy rozwijaniu witryny. Jest to darmowe narzędzie, które możesz pobrać ze strony www.microsoft.com/web (a tutaj bezpośredni link do instalatora – wybierz wersję 2.0). Obsługiwane systemy to: Windows XP, Vista, Windows 7, Windows Server 2003 i Windows Server 2008.
Web Platform Installer daje możliwość szybkiej instalacji i dopasowania programów/bibliotek, których możesz potrzebować do rozwoju bądź publikacji aplikacji okienkowych lub webowych na serwerze Windows’owym. Narzędzie to potrafi automatycznie sprawdzić aktualną konfigurację systemu, pozwala łatwo zaznaczyć elementy które mają być pobrane, a następnie automatycznie je instaluje, gdy klikniesz przycisk “Install” (dzięki temu nie musisz zajmować się każdym z tych elementów ręcznie).
Na przykład możesz kliknąć sekcję “Web Server”, aby wybrać, które moduły IIS chcesz mieć zainstalowane. Wśród nich znajdziesz moduły zawarte w systemie operacyjnym, jak i dodatkowe moduły dostępne do pobrania. Poniżej zaznaczyłem do instalacji dwa dodatkowe moduły - “Aplication Request Routing” i “URL Rewrite”:
Moduł “URL Rewrite” jest darmowy i dostarcza go Microsoft. Ułatwia on użycie dowolnych URL’i w witrynie i optymalizację ich pod kątem SEO. Możesz wymusić zasady SEO (zgodność URL’i, słowa kluczowe, itp.) i dostosowanie URL’i witryny tak, aby odpowiadały Twoim potrzebom (w narzędziach do zarządzania znajdziesz nawet pomoc związaną z tworzeniem wyrażeń regularnych):
Moduł Application Request Routing również jest darmowy i dostarczany przez Microsoft, umożliwia on zbalansowanie obciążenia serwerów w przypadku użycia wielu maszyn (ułatwia skalowanie, przesunięcie serwerów za firewall DMZ i dołączania oraz odłączanie serwerów z farmy bez zakłóceń).
Oprócz tych dwóch modułów możesz zainstalować jeszcze wiele innych w tym takie, które są odpowiedzialne za WebDAV, Secure FTP, automatyczny deployment, zdalne zarządzanie bazę danych poprzez IIS, media streaming, itd. Możesz też zainstalować dodatki takie jak: ASP.NET MVC, .NET 3.5 SP1, Sql Express i powiązane z nim narzędzia administracyjne, Visual Web Developer 2008 i wiele więcej.
Windows Web Application Gallery
Web Platform Installer integruje się również z dostępną online galerią aplikacji webowych: www.microsoft.com/web/gallery
Umożliwia ona szybkie zainstalowanie istniejących aplikacji na serwerze. Galeria zawiera różne popularne, opensource’owe aplikacje .NET’owe (jak DotNetNuke, ScrewTurn Wiki i Umbraco), ale też aplikacje PHP-owe (np. WordPress, Drupal). Możesz łatwo je zainstalować i przeglądać używając Web Platform Installer (w zakładce “Web Applications”):
Oprócz pobrania aplikacji Web Platform Installer utworzy nowy katalog wirtualny i skonfiguruje aplikację, może również stworzyć bazę danych dla aplikacji.
Podsumowanie
Jeśli jeszcze nie pobrałeś Web Platform Installer, to mogę spokojnie Ci polecić przetestowanie go. Myślę, że zauważysz jak prosty stanie się proces instalowania wymaganego oprogramowania, komponentów IIS, czy też gotowych aplikacji webowych. W planach mamy również dodawanie kolejnych funkcjonalności.
Możesz pobrać i zacząć używać Web Platform Installer 2.0 Beta już dziś. Wersja finalna ukaże się już za kilka miesięcy – w lecie.
Scott
Ten post jest tłumaczeniem oryginału napisanego przez Scott’a Guthrie’go, który znajduje się na stronie http://weblogs.asp.net/scottgu/archive/2009/06/03/iis-search-engine-optimization-toolkit.aspx.
This is translation of original post by Scott Guthrie - http://weblogs.asp.net/scottgu/archive/2009/06/03/iis-search-engine-optimization-toolkit.aspx.
SEO (search engine optimization) to jeden z najważniejszych elementów, które należy uwzględnić podczas projektowania portalu. Znaczny procent odwiedzin portali opiera się o ruch pochodzący z wyszukiwarek, a dobre wykorzystanie SEO może jeszcze bardziej powiększyć popularność witryny.
Podobnie, nawet małe błędy mogą poważnie obniżyć skuteczność przeszukiwania witryny przez roboty i spowodować, ze ruch który powinien do danej strony trafić, nie będzie tam odpowiednio kierowany. Niektóre z tych błędów to: wiele adresów prowadzących do tej samej zawartości, niedziałające linki, źle dobrane tytuły, opisy i słowa kluczowe, duża ilość viewstate, zła konstrukcja markup'u, itp. Te błędy są często łatwe do naprawienia – problem w tym, jak je w każdym serwisie wykryć i oznaczyć.
Wprowadzenie do IIS Search Engine Optimization Toolkit
Dzisiaj (03.06.08r.) upubliczniona została wersja beta nowego darmowego narzędzia - IIS Search Engine Optimization Toolkit – który ułatwia przeprowadzenie analizy SEO dla serwisu oraz odnalezienie i poprawienie zawartych w nim błędów.
IIS Search Engine Optimization Toolkit można zainstalować przy użyciu Microsoft Web Platform Installer – bezpośredni link “install now” znajduje się na stronie domowej IIS SEO Toolkit.
Po ukończeniu instalacji odnajdziesz nową sekcję “Search Engine Optimization” oraz kilka narzędzi SEO w menedżerze IIS 7.
Narzędzia Robots i SiteMap ułatwiają utworzenie i zarządzaniem plikami robots.txt i sitemap.xml, które wskazują robotom wyszukiwarek, które adresy URL powinny być przeskanowane, a które nie.
Narzędzie Site Analysis umożliwia przeskanowanie witryny tak, jak zrobiłaby to wyszukiwarka, a następnie analizę treści pod kątem problemów związanych z SEO i dostępnością.
Wprowadzenie do IIS SEO Toolkit’s Site Analysis Tool
Zobaczmy, jak możemy użyć Site Analysis Tool, aby szybko sprawdzić zgodność witryny z SEO. Aby nikogo nie ośmieszyć skanując jego portal, zdecydowałem, że jako cel Site Analysis ustawię jedną z moich własnych witryn: www.scottgu.com. Napisałem tą witrynę już dość dawno temu (ostatni update przypada na 2005). Jeśli zainstalujesz IIS SEO Toolkit możesz wskazać na moją witrynę i powtórzyć poniższe kroki, by zbadać ją pod kątem SEO.
Uruchomienie Site Analysis Tool
Zaczniemy od włączenia menedżera IIS (inetmgr) i kliknięcia na główną gałąź znajdującego się po lewej stronie drzewka elementów IIS (nazwa komputera – w tym przypadku “Scottgu-PC”). Następnie zaznaczmy ikonę “Site Analysis” w sekcji Search Engine Optimization po prawej stronie. Otwierając Site Analysis na poziomie komputera w ten sposób możemy wykonać analizę dowolnej witryny, a nie tylko lokalnej, jak byłoby to w przypadku, gdybyśmy mieli zaznaczony jedną z lokalnych witryn.
Otwarcie narzędzia Site Analysis spowoduje otworzenie poniższego widoku – na liście wyświetlone są wszystkie raporty, które zostały do tej pory utworzone. Ponieważ jeszcze nie używaliśmy Site Analysis, lista jest pusta. Kliknijmy “New Analysis..” w znajdującym się po prawej stronie panelu “Actions”. aby utworzyć nowy raport:
Kliknięcie na “New Analysis..” spowoduje otwarcie okna dialogowego (poniższy screen), który pozwoli nam na nazwanie raportu, jak również wybranie witryny, która ma zostać poddana analizie i określenie “głebokości” analizy.
Nazwijmy nasz nowy raport “scottgu.com” i skonfigurujmy go tak, aby rozpoczął z adresem scottgu.com, a następnie przeskanował do 10 tysięcy stron w obrębie witryny (jeśli nie widzisz pola “Start URL” to oznaczana, że nie zaznaczyłeś głównej gałęzi serwera – cofnij się, zaznacz ją i wtedy kliknij link “Site Analysis”).
Kiedy klikniemy przycisk “Ok” w powyższym oknie narzędzie Site Analysis wyśle żądanie adresu http://www.scottgu.com, przeanalizuje zwrócony HTML i będzie analizować kolejne odnośniki tak, jak robiłby to robot. Moja witryna ma 407 różnych adresów, a IIS SEO wykonując analizę każdej z tych stron potrzebował jedynie 13 sekund, by ją przeprowadzić.
Gdy IIS SEO Toolkit zakończy analizę, zostanie otwarty raport przedstawiający efekt tej analizy. Poniżej widać, że Site Analysis znalazł 721 różnych błędów w całej mojej witrynie:
Możesz kliknąć na dowolny z tych błędów, by przejrzeć jego detale. Za chwilę spojrzymy na kilka z nich.
Badanie błędów “The description is missing”
Jak łatwo zauważyć, moja witryna ma 137 błędów typu “The description is missing”. Kliknijmy na niego podwójnie, by dokładniej go oglądnąć i przejrzeć jego detale. Podwójne kliknięcie na opis otworzy nową zakładkę z filtrowaną listą opisów błędów i wstępnie wypełni kryteria (możesz samemu zmieniać kryteria, a nawet wyeksportować dane do Excela jeżeli potrzebujesz przeprowadzić dokładniejszą analizę danych):
Podwójne kliknięcie na błąd z powyższej listy spowoduje otwarcie okienka z jego detalami. Każdy błąd ma dokładnie opisany powód oraz proponowane rozwiązanie:
Zauważ, że tutaj zapomniałem dodać tag <meta> do strony ze zdjęciami (tak jak na innych stronach). Ponieważ ta strona wyświetla jedynie zdjęcia, roboty wyszukiwarek nie są w stanie określić, co znajduje się na stronie. Opis zawierający od 25 do 150 znaków mógłby objaśniać, że jest to album ze zdjęciami i jaką treść zawiera.
Zakładka “Word Analysis” jest często przydatna przy tworzeniu i badaniu opisu. Można na niej znaleźć szczegóły strony (tytuł, słowa kluczowe, itp.) i listę użytych słów – włącznie z ilością ich powtórzeń. Pozwala też na odnalezienie dwu- i trzywyrazowych fraz powtarzających się na stronie. Jest też lista tytułów linków prowadzących do danej strony – wszystko, co może się przydać, kiedy zajmujemy się opisem strony:

Badanie błędów “URL is linked using different casing”
Spójrzmy teraz na błędy, które dotyczą sytuacji, kiedy to adresy URL nie są utrzymywane w stałej konwencji wielkich liter w odpowiednich miejscach. Zrobimy to klikając na jeden z nich na głównej liście raportu:
Roboty wyszukiwarek liczą ilość stron w Internecie, które w treści mają link do danego URL’a, a ta ilość jest używana podczas obliczania wartości strony podczas wyszukiwania. To oznacza, że jeśli 1000 stron zawiera link do danego URL’a, wyszukiwarka uzna, że ta strona jest bardziej trafna od takiej, do której linki zawiera tylko 10 stron.
Wiele ludzi nie zdaje sobie sprawy z faktu, że roboty wyszukiwarek zwracają uwagę na wielkie litery, a więc URL’e zawierające wielkie litery w innych miejscach są traktowane jako różne. To oznacza, że linki do /Photos.aspx i /photos.aspx będą często traktowane przez roboty nie jako jeden i ten sam, a jako różniące się od siebie. W efekcie, jeżeli połowa linków prowadzi do /Photos.aspx, a połowa do /photos.aspx, to roboty nie będą tej strony uznawać za tak wartościową, jak faktycznie powinna być (zamiast tego, będzie miała tylko jakby połowę wartości). W związku z tym, odnajdywanie i naprawianie miejsc, gdzie wielkie litery zostały błędnie użyte jest bardzo ważne.
Gdy klikniemy na błąd “URL is linked using different casing” powyżej, ujrzymy filtrowaną listę wszystkich 104 URL’ów, które mają kilka wersji w kontekście wielkich liter:
Kliknięcie na którykolwiek z tych URL’i spowoduje pokazanie detali a temat błędu i wyświetlenie wszystkich wersji różnych od siebie pod kątem wielkich liter. Zauważ poniżej jak niewielka różnica powoduje traktowanie URL’i jako różne. W tym przypadku w jednym URL’u jako parametr w querystring mam “AlbumId”, a w innym “albumid” (a więc małe “a” i “i”). Roboty wyszukiwarek będą w efekcie traktować te URL’e jako różne od siebie, a ja nie osiągnę najlepszej pozycji w wynikach wyszukiwania:
Wiedza o tym problemie jest pierwszym krokiem do sukcesu. Następny jest zwykle trudniejszy: odnalezienie wszystkich stron na których są te linki i ustawienie we wszystkich wielkich liter w odpowiednich miejscach. Często naprawisz jakiś błąd i będziesz myśleć, że rozwiązałeś cały problem – tylko po to, żeby się dowiedzieć, że jest jeszcze jakaś część kodu w której też trzeba to poprawić. Możesz sobie ten proces jednak znacznie ułatwić – w menu “Actions” (w prawym górnym rogu) odnajdziesz pozycję “View Routes to this Page”.

Po kliknięciu na nią zobaczysz okienko z listą wszystkich stron, które zaprowadziły robota do URL’a. Poniżej widać, że odnalazł on dwie drogi prowadzące do tego URL’a:

Możliwość dostępu do bardzo dokładnych szczegółów problemów związanych z wielkimi literami w adresach URL znacznie ułatwia naprawienie tych problemów i pozwala zaoszczędzić dużo czasu.
Badanie stron do których prowadzi URL o różnych postaciach
Poprawienie błędów związanych z wielkimi literami to dobry sposób na wstępne polepszenie wartości stron w wyszukiwarce. Chcemy jednak również mieć możliwość naprawienia sytuacji, kiedy ta sama treść może być uzyskana poprzez URL’e, które różnią się nie tylko wielkimi literami. Aby to zrobić wróćmy do głównej listy raportu i spójrzmy na błędy “page contains multiple canonical format violations”:
Gdy spojrzymy na szczegóły błędu, zobaczymy listę stron w naszej witrynie, które mogą zostać otwarte przy użyciu URL’i o różnych postaciach:
Kliknięcie na którąkolwiek z nich spowoduje wyświetlenie szczegółów problemu. Zauważ na poniższym screen’ie, że Analysis Tool wykrył, iż część linków do strony domowej prowadzi do “/”, a część do “/Default.aspx”. Serwer witryny będzie interpretował oba te adresy jako jeden i ten sam, ale roboty wyszukiwarek będą traktować je jako oddzielne, w związku z czym tak, jak w przypadku wielkich liter – spowoduje to obniżenie wartości strony w wyszukiwarce.
Gdy klikniemy na zakładkę “Links”, zobaczymy wszystkie przypadki, gdzie używany jest “/Default.aspx”. Pokaże to strony, które zawierają link do “Default.aspx”, jak również strony, do których linki znajdują się w “/Default.aspx”:
Możemy przełączyć widok, by zobaczyć szczegóły o tym, gdzie i jak został użyty URL “/” klikając na menu “Related URLs” powyżej – to pozwoli nam wyświetlić wszystkie inne URL’e prowadzące do tej treści i pozwoli na szybkie sprawdzenie ich szczegółów:
Podobnie, jak przy błędach związanych z wielkimi literami, możemy użyć “View Routes to this Page”, aby sprawdzić wszystkie URL’e w obrębie witryny, które różnią się od siebie i prowadzą do tej samej treści, a następnie poprawić je w łatwy sposób.
Zauważ, że poprawienie URL’i ww. sposobami jest dobrym pierwszym krokiem, ale do pełnego sukcesu brakuje nam poprawienia linków w zewnętrznych witrynach. Prościej jednak jest ściągnąć i zainstalować IIS URL Rewrite na naszym serwerze, ponieważ dzięki temu unikniemy ręcznego poprawiania URL’i w różnych miejscach, co czasami może być niemożliwe. Permanentny redirect sprawi, że roboty wyszukiwarek będą te URL’e traktować jako jeden i ten sam. IIS URL Rewrite możesz ściągnąć i zainstalować przez Microsoft Web Platform Installer, a instrukcję jak go skonfigurować znajdziesz na tej stronie.
Badanie błędnych przekierowań
Naszym ostatnim krokiem niech będzie poprawienie błędnie utworzonych przekierowań:
Kiedy przeglądałem tą kategorię przypomniało mi się coś, co zrobiłem parę lat temu (kiedy przenosiłem mój blog na inną witrynę) – co jak odkryłem było dość głupie.
Kiedy wystartowałem moją witrynę, posiadałem prosty blog na stronie www.scottgu.com/blog.aspx. Po kilku tygodniach zdecydowałem, że przeniosę swój blog do weblogs.asp.net/scottgu. Zamiast poprawiać linki na wszystkich moich stronach, pomyślałem, że będę sprytny i po prostu na stronie blog.aspx ustawię redirect po stronie serwera do URL’a weblogs.asp.net/scottgu.
Z punktu widzenia zwykłego użytkownika działa to poprawnie, ale jest coś, czego nie zauważyłem przed użyciem Site Analysis. Chodzi mianowicie o to, że roboty nie są w stanie prześledzić tego przekierowania, bo Community Server, który obsługuje weblogs.asp.net wykonuje dla URL’a weblogs.asp.net/scottgu kolejne przekierowanie do http://weblogs.asp.net/scottgu/ (zauważ, że na końcu jest slash).
Biorąc pod uwagę błąd wyświetlany w Site Analysis, roboty nie śledzą już dalej danej strony, gdy spotkają dwa przekierowania pod rząd. Site Analysis wykrył, że blog.aspx przekierowuje do zewnętrznego linku, który przekierowuje do kolejnego linku:
Mogłem potwierdzić ten problem bez otwierania kodu źródłowego strony. Wystarczyło, że przeszedłem do zakładki “Headers” w szczegółach błędu i przeglądnąłem odpowiedź serwera. Nie zawierała ona końcowego slasha, co spowodowało kolejny redirect, tym razem po stronie Community Server:
Poprawienie tego błędu jest proste. Jednak nigdy bym do nie zauważył, gdyby nie pomoc ze strony Site Analysis.
Wsparcie dla automatycznego poprawiania błędów – w przyszłości
Jest jeszcze sporo błędów i problemów, które odnalazł Site Analysis Tool badając moją witrynę. Poprawienie ich jest proste i bardzo podobne do sposobów przedstawionych powyżej. Eliminacja każdego z nich sprawia, że witryna jest łatwiejsza do analizy przez roboty i będzie miała wyższą pozycję w wynikach wyszukiwania. To zaś zwiększy ruch pochodzący z wyszukiwarek. Po wygenerowaniu raportu, będzie on dostępny na liście dostępnych raportów. W dowolnym momencie można też analizę przeprowadzić, żeby sprawdzić, czy nie pojawiły się nowe błędy (zrobisz to w menu kontekstowym elementu raportu na liście).
Aktualna wersja Site Analysis sprawdza witrynę pod kątem około 50 reguł. Z czasem będziemy dodawać więcej reguł, zwiększając dokładność analizy. W przyszłości zobaczysz też więcej inteligencji ze strony Site Analysis, np. z jego pomocą będziesz mógł sprawdzić poprawność konfiguracji IIS URL Rewrite lub pozwoli automatycznie poprawić błąd poprzez wybór najlepszego z sugerowanych rozwiązań. To sprawi, że SEO Twojej witryny będzie jeszcze łatwiejsze do poprawienia. Na razie jednak przynajmniej w kwestii konfiguracji URL Rewrite odsyłam do:
Podsumowanie
IIS Search Engine Optimization Toolkit upraszcza analizę i poprawienie witryny pod kątem zgodności z SEO. Wskazuje naruszenia zasad SEO i proponuje rozwiązania problemów. Możesz dowiedzieć się o nim więcej na stronach:
IIS SEO Toolkit jest darmowy, a jego instalacja trwa mniej niż minutę, może służyć do analizy dowolnej witryny. Nie musisz go instalować na serwerze gdzie utrzymujesz swoją witrynę – wystarczy, że wpiszesz jej adres – a w efekcie dostaniesz gotową analizę.
Aktualna wersja jest oznaczona jako beta, więc jeśli zauważysz jakieś błędy lub masz jakiekolwiek sugestie co do tej aplikacji to daj nam znać na IIS Search Engine Optimization Toolkit Forum.
Scott
Z uwagi na fakt, że jest to pierwsze tłumaczenie z tej serii – szczególnie proszę o uwagi na jego temat. Jeśli coś zwróciło Twoją uwagę – pisz w komentarzach.
Wczoraj (tj. 06.05.2009) pojawił się nowy preview - Preview 4 bibliotek CRUD dla ASP.NET, a więc Dynamic Data. W moim moralnym obowiazku jako fana DD znajduje się w związku z tym opisanie nowego release’u. Ten post zapoczątkuje serię na temat Dynamic Data, w wersji aktualnej, a później Futures, tak aby przekonać programistów ASP.NET, że Dynamic Data nie gryzie.
Do kogo jest skierowany ten post?
Głównie do ludzi, którym Dynamic Data się przyda. Więc raczej nie do tych, którzy pracują nad projektami klasy Enterprise, potężnymi aplikacjami wymagającymi sporej skalowalności, a do tych, którzy pracują nad projektami mniejszymi, zwłaszcza tymi które nie wymagają szczególnej szybkości działania, czy skalowalności. Wynika to przede wszystkim z faktu, że DD nie jest szczególnie szybkie. Warto wspomnieć, iż DD jest z samej nazwy dynamiczne i to powoduje, że przy każdym request’cie snuje się za nami Reflection wczytujące z klas zarządzających danymi model. Reszta już w miarę działa, ale Reflection niestety jest poważnym obciążeniem dla serwera. Wniosek prosty: Jeśli chcesz sprawdzic, czy to jest dla Ciebie – zrób sobie benchmark. Ściągnij release z Codeplex, a następnie w global.asax z wybranego projektu podmień klasę modelu na swój model. Jeśli prędkość Cię zadowoli wróć tutaj, bo tu znajdziesz sporo ciekawych informacji o DD.
Nowy preview Dynamic Data – i co z tego?
Ano, parę ciekawych usprawnień – weźmy np. nowy, superprzyspieszony sposób rejestrowania modelu – przykład skradziony z samples.
Szybko wrzucamy na stronę GridView:
5 <html xmlns="http://www.w3.org/1999/xhtml" >
6 <head runat="server">
7 <title></title>
8 </head>
9 <body>
10 <form id="form1" runat="server">
11 <div>
12
13 <asp:GridView ID="GridView1" runat="server" AutoGenerateEditButton="true"
14 onrowcancelingedit="GridView1_RowCancelingEdit"
15 onrowediting="GridView1_RowEditing" onrowupdating="GridView1_RowUpdating">
16 </asp:GridView>
17
18 </div>
19 </form>
20 </body>
21 </html>
W kodziku:
7 public partial class DataTableSample : System.Web.UI.Page {
8 DataTable dataTable;
9 protected void Page_Init() {
10 // Get DataTable
11 dataTable = Products.GetProductsTable();
12
13 // Add some metadata
14 var productNameMd = dataTable.Columns["ProductName"].ExtendedProperties;
15 productNameMd["Required"] = true;
16 productNameMd["UIHint"] = "FooBar";
17
18 GridView1.EnableDynamicData(dataTable);
19 }
20
21 protected override void OnPreRender(EventArgs e) {
22 GridView1.DataSource = dataTable;
23 GridView1.DataBind();
24 base.OnPreRender(e);
25 }
26
27 protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e) {
28 GridView1.EditIndex = e.NewEditIndex;
29 }
30
31 protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e) {
32
33 }
34
35 protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e) {
36
37 }
38 }
39 }
A za darmo dostajemy coś takiego:
Mamy tu inline editing, walidację po stronie serwera i klienta, możliwość customizowania wyglądu i parę innych bajerów, o których napiszę wkrótce. Ale generalnie – mamy to wszystko przy pomocy jednej linii kodu ( GridView1.EnableDynamicData(dataTable); ), bo reszta to zwykłe bindowanie danych do GridView i dodanie prostej walidacji (to powinno było zostać wykonane w modelu). Zobacz przykład SimpleDynamicDataSamples, a poczujesz o co chodzi. A chodzi tu o coś, co uczyniłoby z DD niesamowitą platformę CRUD już teraz, gdyby nie błędny sposób reklamowania jej przez twórców.
Podoba mi się to!
Mi też się podoba – możesz więc tak jak ja zacząć z tego korzystać tak szybko, jak to możliwe. Ale jeszcze poświeć chwilę – zrób benchmark i sprawdź czy DD nie jest za wolne dla Ciebie – jeśli nie, to witaj w gronie szczęśliwych użytkowników Dynamic Data.
I to wszystko tak po prostu?
Niestety nie, życie byłoby wtedy za łatwe – na te bajery musisz poczekać do .Net 4.0, bo po zobaczeniu tego na pewno nie wystarczy Ci to, co jest dostępne dziś – ale zawsze możesz spróbować.
Wymagania
Dla dzisiejszej platformy i dla Futures .Net 3.5 SP1 i Full Trust, dla finalnej to na 90% będzie .Net 4.0 i Full Trust environment.
Spójrz tu w wolnym czasie
Strona Microsoftu o Dynamic Data
Na blogu Scotta Huntera o Preview 4
14 marca 2009 odbyła się darmowa (a jakże!) konferencja Community 2 Community, jednak z racji faktu, że na poprzedniej mnie nie było, mogę opisać jedynie tegoroczną edycję.
Największym problemem była rejestracja internetowa – konkurencja była niesamowita, w turze zamkniętej dla grup miejsca na ścieżkę .Net skończyły się w kilkadziesiąt minut, a w turze otwartej dla wszystkich w około 10 minut.

Sama konferencja zaczęła się od rejestracji – już podczas niej dał się we znaki światowy kryzys, w związku z którym Microsoft wietrzył magazyny rozdając smycze “Visual Studio 2005” ;]. Uprzedzając wyniki mogę powiedzieć, że prawdopodobnie najlepiej ocenioną sesją będzie “Hardcore debugging…” Ingo Rammera. Poniżej mała tabela z opisami sesji i moją subiektywną oceną każdej z nich.
Każda sesja trwała (przynajmniej w teorii) 70 minut. Uczestnicy wypełniali ankiety, więc niedługo powinny się na stronie c2c pojawić wyniki.
| Prelegent | Temat | Opis | Ocena |
| Marek Byszewski | Tour de VSTS 2010 | Marek Byszewski pokazywał, co nowego czeka nas w VSTS 2010, skupiał się przede wszystkim na nowościach TFS, raczej omijał różne feature’y specyficzne dla konkretnych technologii oraz zmiany w wyglądzie, | Marek chciał (dosłownie chciał) pokazać sporo rzeczy na żywo, jednak CTP dostarczone przez Microsoft powodowało nieciekawe problemy, a szkoda bo zapowiadało się ciekawie, na plus – wspomnienie o historycznym debuggerze. (jeśli nie widziałeś – filmik jest pod tabelą). Ogólnie nie najgorzej. (8/10) |
| Julia Lerman | My favorite Entity Framework Tips & Tricks | Julia pokazywała te rzeczy, których po prostu korzystając z EF musisz używać – tricki związane z referencjami wewnątrz EF, Entity SQL, itd… | Julia super prowadziła prelekcje – co prawda niewiele osób na sali przyznało się do używania EF, ale mam nadzieję, że kogoś zachęciła do używania tego frameworka. Na niewielki minus przypada to, że Julia zdecydowała się pisać kod w c#, zamiast VB.NET – co powodowało, że życzliwi słuchacze musieli pomagać w pisaniu. (9/10) |
| Piotr Leszczyński | Kolejny kontener Dependency Injection? NIE - dziękuję! Czyli o koncepcji meta-kontenera słów kilka | Piotr wraz z kolegami z firmy wpadli na pomysł uniezależnienia się od jednego dostawcy IoC, w razie np. zmiany licencji. Meta kontener, miałby służyć jako wrapper do różnych możliwych kontenerów DI – podobnie do Common Service Locator. Podczas sesji były również prezentowane podstawy DI. | Pod koniec sesji w ramach pytań dały się słyszeć głosy: “czy w ogóle to jest potrzebne? – meta kontener niszczy fajne feature’y StructureMapa, czy Spring.Neta, a w zamian daje niewiele” – no właśnie – przecież do zmiany jest tylko bootstrapper i fabryki – a co w wypadku zmiany licencji meta kontenera? Piotr strasznie mocno trzymał się ostatniej mody na żarty wewnątrz prezentacji, przez co nie wszystkie były śmieszne. Nie róbmy wszystkiego na siłę. (6/10) |
| Ingo Rammer | Hardcore Production Debugging of .NET Applications | Ingo pokazywał debuggowanie aplikacji .Net – w różnych scenariuszach, głównie z użyciem WinDbg, w czasie sesji odpowiedział na sporo pytań – od debuggowania zdalnego, aż do dogłębnej analizy dump’ów. | Ingo zaprezentował prawdziwą klasę prezentacji – z humorem, lekkością i finezją – widać było, że jest prawdziwym profesjonalistą, znał również dokładne i precyzyjne odpowiedzi na wszystkie zadawane pytania oraz prezentował te odpowiedzi na żywo. Na plusik żart wykonany za pomocą Global Flags. Szacun dla Ingo. (10/10) |
| Udi Dahan | Avoid a Failed SOA - Business and Autonomous Components to the Rescue | Udi opowiadał jakich błędów należy unikać, aby stworzyć system SOA na najwyższym poziomie. | Sesja była nienajgorsza – i to tyle co można o niej powiedzieć. Czysta teoria przez 70 minut. Nawet wsparcie humorystyczną i bardzo profesjonalną prezentacją nie pomogło tej sesji. Zabrakło choć minimum kodu, czegoś na co można by było spojrzeć. Ale nie ma sie co dziwić, patrząc na temat wiadomo było już od początku, że to będzie coś poważnego. W końcu nie wszyscy słuchacze obecni na ścieżce .Net zajmują się architekturą oprogramowania. (7/10) |
| Artur Paluszyński | Interakcyjne sceny 3D w Windows Presentation Foundation | Artur swoją sesją zakończył ścieżkę .Net. Zaprezentował bardzo ciekawe – a przede wszystkim praktyczne – rozwiązania 3D w WPF. Kontrolki znane w Windows Forms zaczęły egzystować w 3D znajdując swoje miejsce na ścianach sześcianu, a walec wyświetlił film. | Artur pokazał jaką wspaniałą zabawką jest WPF, ale też jaką moc posiada ta technologia. Szybkie stworzenie efektywnego trójwymiarowego interfejsu użytkownika to główny atut WPF. Wraz z postępującymi wymaganiami odbiorcy 3D UI stanie się standardem, a ta sesja pokazała jak szybko i niskim kosztem stworzyć taki interfejs. Tylko dlaczego Artur zwracał się do słuchaczy – per państwo? (8/10) |
Ocena całej konferencji: Było super. Zabrakło może porządnego ciepłego posiłku… ale sesje były ok. No i możliwość pogadania z ludźmi, których najczęściej widzi się tylko jako avatary na codeguru.pl. Ciężko się było dostać, ale jeśli w przyszłym roku będzie kolejna edycja konferencji to oczywiście reflektuję ;). (9/10)
PS. Obiecany powyżej – historyczny debugger.
Ostatnio, tj. kilka godzin temu, przemierzając bezgraniczne przestrzenie Internetu trafiłem na ciekawe biblioteki służące do obsługi bazy danych, a dokładniej przeprowadzania operacji CRUD w uproszczony sposób. Evolutility, bo tak się projekt nazywa, tworzy prosty UI w ASP.NET pozwalając edytować dane w bazie np. Microsoft SQL Server. Wygląd, mimo że dość miły "nie zwala jednak z nóg", więc Evolutility w praktyce bez większej dyskusji nadawałoby się na sekcję administratorską jakiegoś CMS-a/pseudo CMS-a/galerii/innej listy. Ale ten projekt ma raczej małe szanse powodzenia i popularyzacji, ponieważ ma potężnego i świetnie wspieranego konkurenta - DynamicData, który w wersji Futures zapowiada sie super, a przede wszystkim bardzo flexible i łatwy w tworzeniu.
Po niezbyt korzystnym dla Evolutility wstępie czas na test rzeczywisty. Skorzystałem z Evolutility Dictionary - jest to wersja, która posiada możliwość edycji schematów, edytuje więc sama siebie, ponieważ ma również funkcjonalności zwykłej wersji (CRUD). Ściągnąłem na potrzeby testu ten plik.
Rozpakowałem, stworzyłem nową bazę MS SQL i wykonałem na niej 4 kwerendy w określonej kolejności (wg readme): 1- EVOL-Common.sql 2- EVOL-MultiUsers.sql 3- EvoDico.sql 4- DBObjects.sql. Szybciutkie uaktualnienie connectionString w web.config - super, zmieniłem tylko nazwę hosta, reszta się zgadzała. Portalik uruchomił się dość szybko, działa również sprawnie, ma lekki zgrzyt przy ładowaniu modułów edycji bazy. Trochę sobie poedytowalem schematy - niewielkie rozczarowanie tym, że przy edycji schematów z poziomu Evolutility Dictionary data zostaje po stronie bazy chyba nieruszona i zapisuje sie jako nvarchar(200), ale w sumie do przeżycia.
I eksport do np. Excela:
Pomyślałem tylko: “szkoda, że w ostatnim projekcie tego nie wykorzystałem”
Tutaj strona projektu.
Artykuł na Codeproject na temat Evolutility.
PS. Używajcie Windows Live Writer kiedy tylko możecie – genialna sprawa w porównaniu z tymi FckEditorami itd.