Bartek Szafko

all of the bits and pieces

Archive for the ‘ASP .NET MVC’ Category

Kolejna afera z ASP .NET MVC

with 3 comments

O aferze z Oxite było głośno jakiś czas temu. Microsoft wypuścił Oxite jako implementację przykładową przy użyciu asp .net mvc. Niestety aplikacja została bardzo ostro skrytykowana przez środowisko.

Teraz tym razem zdecydowano się wypuścić aplikację pokazującą jak budować serwisy typu web 2.0 przy pomocy ASP .NET MVC. Projekt nazwano KOBE. Tym razem znowu projekt spotkał się z miażdzącą krytyką środowiska, czego najbardziej dobitnym przykładem jest seria postów Orena:

Po takiej fali krytyki Phil Haack ( jeden z PMów asp .net) próbował tłumaczyć jaką stosują taxonomie nazewnictwa. Ciekawe rzeczy działy się także na tweeterze:

image

Po tym całym szumie, nie można już niestety pobrać Kobe – taki tekst jest widoczny na stronie:

This sample application is being updated to incorporate community feedback. An updated version will be released shortly.

Szkoda, że nie ma żadnego sensownego przykładu do pobrania ze strony Microsoftu. Moim zdaniem najlepszy jest przykład Roba Connery MVC StoreFront vel Kona.

W tym kontekście całkiem sensowne jest pytanie Jarka :

Pojawił się ASP.NET MVC 1.0 – interesuje mnie jak sprawa wygląda z komercyjnym zastosowaniem. Czy można już ASP.NET MVC wykorzystywać komercyjnie?

Oczywiście ASP .NET MVC można stosować komercyjnie, nic nie stoi na przeszkodzie. Dostępna jest oficjalnie wspierana wersja 1.0. Licencjonowanie zezwala na komercyjne użycie już od Preview( zdaje się 3), z tym że pomiędzy poszczególnymi wersjami preview nie była zachowywana zgodność. Teraz gdy jest 1.0 już nie ma takiego ryzyka.

Powstało już wiele fajnych aplikacji webowych, które wykorzystują MVC np stackoverflow, więc gra chyba jest warta świeczki. Tylko przykłady i implementacje referencyjne coś się nie udają :P

Written by Bartłomiej Szafko

Kwiecień 20th, 2009 at 7:01 pm

Posted in ASP .NET MVC

Tagged with , ,

Lokalizacja gotowej aplikacji ASP .NET MVC

with 3 comments

image

No dobra, po godzinach też programuje, ale już dla przyjemności ;) dlatego nikt mi za to nie płaci :D

Sytuacja: gotowa aplikacja w ASP .NET MVC – język wszystkich komunikatów to angielski. Dodatkowo aplikacja nie była przystosowana w żaden sposób do lokalizacji. Można powiedzieć, że jest to typowa brownfield application.

Zadanie: spolszczyć całość aplikacji – zachowując przy tym możliwość pokazania interfejsu użytkownika w pierwotnej wersji językowej.

Pierwsze koty za płoty – rozwiązanie gorsze

Pierwsze rozwiązanie jakie przychodzi na myśl to – tłumaczenie wszystkich tekstów z kontrolerów i modyfikacja widoków. Sposób słaby i nie pozwoli na pokazanie interfejsu w oryginalnym języku.

Drugie rozwiązanie – lepsze

Kontrolery

Przeniesienie wszystkich stringów, które podlegają lokalizacji, z Controllerów do resourców w folderze App_LocalResources. Następnie trzeba stworzyć wersje resourców dla każdego języka.

Trzeba jeszcze wziąć pod uwagę, czy komunikaty są budowane za pomocą String.Format – w moim wypadku tak na szczęście było.

Wyciąganie stringów do resourców – to jest naprawdę mordercze zajęcie – na szczęście po małym wyszukiwaniu znalazłem super wtyczkę do Resharpera – RGreatEx. Wtyczka potrafi wyciągnąć stringi do resourców i w ich miejsce wstawić odpowiednie odwołania. Podobno potrafi także tłumaczyć za pomocą google translate, ale do automatycznego tłumaczenia jestem nastawiony sceptycznie.

Widoki

Zdublowanie plików widoków np About.aspx w wersji angielskiej –> About.pl.aspx w wersji polskiej. Wiem, teoretycznie powinienem też wyciągnąć wszystkie stringi do lokalizacji, jednak(odstawiając na bok różne dogmaty) takie rozwiązanie wydało mi się bardzie sensowne. No dobra, teraz tylko sposób żeby ViewEngine w pierwszej kolejności wyszukał stronę About.pl.aspx, a dopiero w drugiej About.aspx. Okazuje się, że najlepiej w tym celu zrobić własny ViewEngine:

public class LocalizationViewEngine : WebFormViewEngine
    {
        public LocalizationViewEngine() : base()
        {
            ViewLocationFormats = AppendCulture(ViewLocationFormats);
            PartialViewLocationFormats = AppendCulture(PartialViewLocationFormats);
            MasterLocationFormats = AppendCulture(MasterLocationFormats);
        }

        private string [] AppendCulture(string[] arr)
        {
            List<string> ret = new List<string>();
            for (int i = 0; i < arr.Length; i++)
            {
                string s = arr[i];
                s = s.Replace(".aspx",
                              "." + Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName + ".aspx");
                s = s.Replace(".ascx",
                              "." + Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName + ".ascx");
                s = s.Replace(".master",
                              "." + Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName + ".master");
                ret.Insert(0, s);
            }
            ret.AddRange(arr);
            return ret.ToArray();
        }

Trzeba tylko jeszcze powiedzieć MVC, że używamy własnego silnika widoków w global.asax.cs:

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new LocalizationViewEngine());

A w web.config zmienić ustawienia globalization:

<globalization
requestEncoding="utf-8"
responseEncoding="utf-8"
culture="en-US"
uiCulture="pl-PL"
/>

Teraz zostaje tylko nudna część tzn.: wygibasy lingwistyczne i tłumaczenie resource oraz widoków. Jak już jest wszystko wymyślone to średnio chce mi się odwalać czarną robotę ;P

Written by Bartłomiej Szafko

Luty 23rd, 2009 at 11:49 pm

Posted in ASP .NET MVC, Development

Oxite

with 2 comments

oxite

Oxite to fajny projekt , którego celem jest zbudowanie silnika blogowego w ASP .NET MVC na licencji Open Source( dokładniej jest to licencje MS-PL, podobno jest kompatybilna z GPL).

W niektórych serwisach został już obwołany jako CMS  co mi się wydaje przesadą, natomiast Rob Connery ma swoim blogu umieścił świetny (obiektywny!!!) wpis na ten temat.

Moją szczególną uwagę przykuła implementacja xml-rpc MetaWeblog, która pozwala na używanie narzędzi do blogowania off-line.

Na blogach pojawiły się już wpisy o tym jak przenieść wpisy z wordpressa, ale to traktuje tylko w kategoriach eksperymentu.

Oxite nie sięga DasBlog i BlogEngine.NET do pięt, a tym bardziej WordPress, co zresztą mówią sami twórcy: This is not an ‘off the shelf’ blogging package.  If you aren’t a developer and just want to get blogging then you should look at one of these great blogging products: Graffiti, SubText, Blog Engine .NET, dasBlog or a hosted service like Wordpress

Podsumowując Oxite na tym etapie rozwoju uznałbym tylko za ciekawy przykład jak można używać ASP .NET MVC.

Written by Bartłomiej Szafko

Grudzień 15th, 2008 at 9:30 pm

Posted in ASP .NET MVC

StackOverflow

without comments


StakckOverflow to bardzo ciekawy projekt. Zadajesz pytania dotyczące tematyki developerskiej a społeczność próbuje udzielić jak najlepszej odpowiedzi. Za darmo! To taki anty expert-exchange. Robi naprawdę duże wrażenie.

Za całością stoi sławny Joel Spolsky.

Dlaczego o tym w ogóle piszę? Okazuje się, że projekt został zrealizowany przy pomocy ASP .NET MVC – to jest chyba pierwszy projekt w MVC uruchomiony na tak szeroką skalę. Co ciekawe do autoryzacji używane jest tylko i wyłącznie OpenId, niestety mój identyfikator z openid.pl najwyraźniej nie jest kompatybilny :(

Więcej info o narzędziach użytych w projekcie.

Na stronie jest też bardzo ciekawy podcast o budowaniu serwisu, założeniach i filozofii społeczności developerów – polecam.

Written by Bartłomiej Szafko

Wrzesień 22nd, 2008 at 9:12 pm

Posted in ASP .NET MVC, Links, Społeczności

ASP .NET MVC Preview 5 – po cichu

without comments

Dzisiaj, bez większych fanfarów, pojawił się preview 5 ASP .NET MVC.

Tak na szybki ogląd release notes widać, że _WRESZCZIE_ dodano obsługę RenderPartial.

Chociaż muszę przyznać, że dodany AJAX mi się nie podoba (przynajmniej na podstawie paru tutoriali, które widziałem), nadal wolę jQuery.

Dodano też obsługę własnych binderów do atrybutu ModelBinder, co akurat mnie cieszy.

Release na codeplex i pełna lista zmian
, niestety na razie bez source’ów.

Jest jeszcze forum na którym można wylewać swoje żale ;)

Written by Bartłomiej Szafko

Sierpień 29th, 2008 at 5:48 pm

Posted in ASP .NET MVC, Pictures

ASP .NET MVC Preview 4 już w tym tygodniu

with one comment

Na blogu Scotta Guthrie ukazała się notatka, że już w tym tygodniu można spodziewać się następnej wersji preview ASP .NET MVC. Post zawiera również pierwszą część opisu zmian, które raczej nie dotyczą przysłowiowych bebechów, tylko nowych funkcjonalności. Muszę przyznać, że czytając posta miałem lekkie deja-vu.

To o czym pisze Scott to:

  • Atrybut HandleError – obsługa błędów opdowiednik Rescue z MvcContrib
  • Atrybut OutputCaheFilter – cachowanie wyników akcji, podobne propozycje można było znaleĽć na wielu blogach
  • Atrybut Authorize – zabezpiecznie wywołania akcji tylko dla określonych, zalogowanych lub posiadających określoną rolę użytkowników. Zamiast tego z powodzeniem można użyć standardowego .netowego PrincipalPermissionAttribute
  • AccountController – czyli domyślny kontroler generowany z szablonem aplikacji realizujący logowanie, rejestrację i przypominanie hasła. Taką funkcję do tej pory pełnił MvcMembership , szkoda tylko że nie ma wsparcia dla Cardspace, ale widać że pewnie inna grupa się tym zajmuje
  • TempData – będzie można testować bez mockowania
  • Jak widać zespół postarał się, żeby dodać wszystko czego brakowało w pudełku z MVC.

    Scott ma w następnym poście napisać o możliwościach użycia AJAXa, ciekaw jestem jak to im wyszło.

    Written by Bartłomiej Szafko

    Lipiec 15th, 2008 at 12:10 am

    Posted in ASP .NET MVC

    Garść linków o ASP .NET MVC

    without comments

    Pogoda specjalnie nie sprzyja pisaniu postów, dlatego tym razem trochę ciekawych moim zdaniem linków o asp .net mvc.

    Trochę podcastów do posłuchania na plaży w weekend :) :

    A teraz czas na relaks!

    Written by Bartłomiej Szafko

    Lipiec 4th, 2008 at 9:05 pm

    Posted in ASP .NET MVC

    MVC Contrib – wszystko czego brakuje w ASP .NET MVC

    without comments

    Do MVC istnieje świetny wspierający projekt społecznościowy MVCContrib.

    Funkcjonalność zawarta w tym projekcie – bibliotece została podzielona na 7 obszarów:

    1. Helpery UI: wsparcie dla DataBinding, formularzy, walidacji danych, grida
    2. Fabryki kontrolerów – wsparcie dla mechanizmów Inversion of Control:Castle Windsor( z konkurencyjnego Monorail), Object Builder, Spring .Net, Structured Map
    3. ¦cieżki(routing): Simply Restful Routing
    4. Kontrolery: klasa ConventionController
    5. Mechanizmy widoków: Brail, NHaml, NVelocity, XSLT
    6. Helper do tworzenia testów
    7. Narzędzia Hash: wsparcie wyrażeń lambda do tworzenia słowników

    Poniżej rozwinięcie punktów z komentarzami i przykładami.

    Read the rest of this entry »

    Written by Bartłomiej Szafko

    Czerwiec 19th, 2008 at 7:43 pm

    Posted in ASP .NET MVC

    Chroń swoje akcje w MVC

    without comments

    Bynajmniej nie będzie w tym poście o rynkach kapitałowych ;)

    Jeden z czytelników niedawno zapytał mnie w jaki sposób chronić akcję przed niepowołanym dostępem.Okazauje się, że ASP .NET MVC z pomocą standardowych komponentów .NET stosunkowo to zrealizować.

    WyobraĽmy sobie, że mamy akcję, którą chcielibyśmy chronić, tak żeby tylko użytkownik o nazwie Administrator mógł ją wywołać:

        1 public ActionResult About()

        2 {

        3     ViewData["Title"] = “About Page”;

        4 

        5     return View();

        6 }

    (używam już składni z preview 3)

    W standardowym .NET istnieje atrybut pozwalający ograniczać dostęp do metod nazywa się PrincipalPermission ( dużo o nim można przeczytać na msdnie). Pozwala on określić, czy żeby uzyskać dostęp, wystarczy być tylko zalogowanym, czy trzeba należeć do określonej roli, czy może mieć konkretną nazwę użytkownika. W wypadku, gdy ktoś niepowołany uzyska dostęp do metody zrzucony zostanie wyjątek SecurityException.

    Jednak, takie zachowanie(rzucanie wyjątkami) nie jest porządanym zachowaniem dla naszej aplikacji w MVC, trzeba by przekierować użytkownika na przykład na stronę logowania. W MVC istnieje pojęcie filtrów( dziedziczących po ActionFilterAttribute), które pozwalają przechwytywać wykonywanie akcji i realizować określone zadania, przykładowy filtr mógłby wyglądać tak(tylko najważniejszy kod, reszta do ściągnięcia):

        1 public override void OnActionExecuted(ActionExecutedContext filterContext)

        2  {

        3     Exception exception = filterContext.Exception;

        4 

        5     if (exception == null)

        6         return;

        7 

        8     foreach (Type exceptionType in ExceptionTypes)

        9     {

       10         if (exceptionType.IsAssignableFrom((exception.InnerException ?? exception).GetType()))

       11         {

       12             filterContext.ExceptionHandled = true;

       13 

       14             if (Redirect)

       15             {

       16                 RouteValueDictionary routes = new RouteValueDictionary();

       17                 routes.Add(“Action”, Action);

       18                 routes.Add(“Controller”, Controller);                     

       19                 filterContext.Result = new RedirectToRouteResult(routes);

       20             }

       21             else

       22             {

       23                 filterContext.HttpContext.Response.Clear();

       24 

       25                 filterContext.HttpContext.Response.StatusCode = ResponseCode;

       26                 filterContext.HttpContext.Response.StatusDescription = ResponseDescription;

       27 

       28                 filterContext.HttpContext.Response.ContentType = “text/html”;

       29                 filterContext.HttpContext.Response.Write(“<html><head><title>” + ResponseDescription + “</title></head><body>”);

       30                 filterContext.HttpContext.Response.Write(“<h2>” + ResponseDescription + “</h2>”);

       31                 filterContext.HttpContext.Response.Write(“<p>” + (exception.InnerException ?? exception).Message + “</p>”);

       32                 filterContext.HttpContext.Response.Write(“</body></html>”);

       33                 filterContext.HttpContext.Response.Flush();

       34 

       35                 filterContext.HttpContext.ApplicationInstance.CompleteRequest();

       36             }

       37         }

       38     }

       39  }

    ( przykład zapożyczony z biblioteki ManagedFusion – spodobało mi się to podejście)

    Teraz wystarczy przerobić naszą akcję, aby wyglądała tak:

        1 [PrincipalPermission(SecurityAction.Demand, Name = "Administrator")]

        2 [ExceptionHandler("Login", "Uzytkownik", typeof(SecurityException))]

        3 public ActionResult About()

        4 {

        5     ViewData["Title"] = “About Page”;

        6 

        7     return View();

        8 }

    Spowoduje to, przekierowanie użytkownika do akcji Login w kontrolerze Uzytkownik.

    Oczywiście należy zatroszczyć się, aby do aplikacji można było się zalogować – można w tym celu użyć normalnej autentykacji forms albo dowolnej innej obsługiwanej w asp .net. Standardowe MembershipProvidery i RoleProvidery też dadzą się użyć.

    Do ściągnięcia jest kod przykładowej aplikacji z autoryzacją Forms, nie jest on w żadnym wypadku produkcyjny, a jego napisanie zajęło mi tylko 20 minut.

    Polecam także świetny artykuł Roba Connery na ten temat

    Written by Bartłomiej Szafko

    Czerwiec 12th, 2008 at 3:01 pm

    Posted in ASP .NET MVC

    ASP .NET MVC Preview 3

    without comments

    Od 27 maja dostępny jest Preview 3 ASP .NET MVC. O najważniejszej zmianie, czyli o nowym sposobie obsługi renderowania widoków wspominałem już wcześniej. Dzisiaj trochę więcej szczegółów i przykładów.

    Wszystkie akcje muszą teraz zwracać ActionResult:

    public ActionResult Index()

    {

        ViewData["Title"] = “Home Page”;

        ViewData["Message"] = “Welcome to ASP.NET MVC!”;

        return View();

    }

    ActionResult jest klasą abstrakcyjną, z której dziedziczy:

    Dzięki takim zmianom testowanie akcji jest możliwe bez mockowania całego contextu http:

    [TestMethod]

    public void Index()

    {

        // Setup

        HomeController controller = new HomeController();

     

        // Execute

        ViewResult result = controller.Index() as ViewResult;

     

        // Verify

        ViewDataDictionary viewData = result.ViewData as ViewDataDictionary;

        Assert.AreEqual(“Home Page”, viewData["Title"]);

        Assert.AreEqual(“Welcome to ASP.NET MVC!”, viewData["Message"]);

    }

    Inne:

    Jak zwykle przy okazji MVC polecam wpis na blogu Scotta jest tam dużo informacji także o pozostałych zmianach.

    Preview 3 można ściągnąć w Ľródłach i binariach.

    Written by Bartłomiej Szafko

    Czerwiec 8th, 2008 at 8:22 pm

    Posted in ASP .NET MVC

    This work by Bartłomiej Szafko is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Polska.