Instalacja androida na HyperV

Instalacja jest dokładnie opisana tutaj. Ja napotkałem na problem, że podczas instalacji nie był widoczny dysk twardy.

Rozwiązanie znalazłem na tej stronie:

Press CTRL + ALT + F2 to find a root shell. Here, we load the module for Hyper-V storage driver:

Go back to the menu by pressing CTRL + ALT + F1, you should be able to partition your hard drive and continue with the installation.

Odnośniki

  • http://www.mb4.pl/?p=1493 opis instalacji
  • http://latenightcodehacking.blogspot.it/2013/07/installing-android-x86-version-42-on.html stąd zaczerpnąłem rozwiązanie z dyskiem, ale jest tam opis innych problemów

Lucy Html Extension

Biblioteka Lucy powstała jako niewielkie rozszerzenie genialnego pakietu NancyFx. Potrzeba drobnych rozszerzeń pojawiła się podczas migracji pewnego projektu ASP.NET MVC do NancyFx. Zabrakło kilku rozszerzeń ułatwiających prostą migrację szablonów Razor. Krótki zbiór porównawczy niektórych funkcji przedstawiam w poniższej tabeli

ASP.NET MVC Nancy Lucy
Wskazanie klasy modelu i opcjonalnie klasy bazowej dla widoku  @model TModel @inherits NancyRazorViewBase<TModel> @inherits LucyRazorViewBase<TModel>
Otwarcie formularza  @using (Html.BeginForm())  <html … > @using (Html.BeginForm())
 Sprawdzenie roli użytkownika  User.IsInRole(„RoleName”))  ? Html.UserIsInRole(„RoleName”)

 

A tutaj są zamienniki, których należy użyć migrując ASP.NET MVC do Nancy lub Lucy.

ASP.NET MVC Nancy/Lucy
Sprawdzenie czy żądanie jest po https Request.IsSecureConnection RenderContext.Context.Request.Url.IsSecure
Czy użytkownik zalogowany Request.IsAuthenticated Html.IsAuthenticated
Nazwa zalogowanego użytkownika User.Identity.GetUserName() RenderContext.Context.CurrentUser.UserName
lub
Html.CurrentUser.UserName

Lucy oferuje także kilka rozszerzeń, które nie mają wprost odpowiedników w omawianych frameworkach

  • @Html.Link("Nazwa odnośnika", "url", dodatkowe_atrybuty)
    np:
    @Html.Link("Main page", "~/", new { @class = "navbar-brand" })

IDisposable – wzorzec

Podam tutaj w skróconej wersji wzorzec, ponieważ chcę go mieć pod ręką dla zbrodniczej praktyki Ctrl+C, Ctrl+V.

Klasa bazowa z IDisposable

Klasa dziedzicząca po klasie implementującej IDisposable

 

Źródła

Autoryzacja Nancy.Authentication.Forms

Postaram się pokazać jak użyć Nancy.Authentication.Forms dla projektu, który jest migrowany z ASP.NET MVC do platform NancyFx + PetaPoco. Połączenie NancyFx i PetaPoco wydaje się bardzo lekkim rozwiązaniem, które jest w stanie przejąć na siebie zadania ociężałego tandemu MVC + EntityFramework.

Instalacja

Aby skorzystać z Nancy.Authentication.Forms należy najpierw zainstalować pakiet używając NuGet

Jeśli pakiet PetaPoco nie jest jeszcze zainstalowany to należy go dodać właśnie teraz.

Konieczny także będzie pakiet Microsoft.AspNet.WebPages, z uwagi na klasę System.Web.Helpers.Crypto pomocną przy operacjach na hasłach.

Zaczynamy programowanie

Spadek po ASP.NET Identity

Migrując istniejący projekt ASP.NET MVC zapewne mamy zestaw tabel w bazie, które zawierają informacje o użytkownikach. Szczęśliwie możemy posłużyć się istniejącą tabelą AspNetUsers, której pole Id zdefiniowane jako nvarchar(128) w rzeczywistości przechowuje GUIDy. Nie spotkałem się przynajmniej z inną sytuacją. Czemu Guid jest ważny? Okaże się za chwilę.

Zdefiniujmy klasy modelu z użyciem anotacji PetaPoco:

IUserIdentity

Następnie należy zaimplementować kilka interfejsów. Na początek IUserIdentity, który przechowuje podstawowe informacje o zalogowanym użytkowniku czyli jego nazwę i zestaw udzielonych mu praw.

IUserMapper

Z użyciem tej klasy zaimplementujemy interfejs Nancy.Authentication.Forms.IUserMapper. Zadaniem klasy implementującej ten interfejs jest dostarczenie informacji o użytkowniku (w postaci instancji IUserIdentity) na podstawie identyfikatora, którym jest Guid.

Podłączenie do NancyFx

Stworzone powyżej mechanizmy należy podłączyć do Nancy. Do tego celu posłużę się klasą Bootstrapera, który jest odpowiedzialny za wiele aspektów pracy frameworka.

IUserMapper

Jeśli w projekcie wcześniej nie został dodany Bootstraper to należy teraz dodać nową klasę dziedziczącą po DefaultNancyBootstrapper. Poniższy dodatek rejestruje klasę NancyUserMapper w kontenerze IoC. Dla mniej wtajemniczonych: oznacza to tyle, że kiedy gdzieś potrzebna będzie klasa implementująca interfejs IUserMapper to kontener IoC stworzy instancję stworzonej przez nas klasy NancyUserMapper.

Endy Tjahjono pisze, że jest to krok opcjonalny, po szczegóły odsyłam do jego artykułu – link na dole artykułu.

Aktywacja FormsAuthentication

Druga zmiana bootstrapera aktywuje mechanizm FormsAuthentication poprzez dołączenie go na początku kolejki przetwarzania żądania HTTP. Jednocześnie podana jest tam ścieżka ~/login, gdzie klient zostanie przekierowany w przypadku próby nieautoryzowanego dostępu do chronionego adresu url. Jak łatwo się domyślić pod adresem /login/ znajdzie się formularz logowania.

Formularz logowania

Obsługę formularza logowania zaimplementujemy w module LoginModule wspomaganym widokiem Login.cshtml. Jako model posłuży klasa LoginModel.

Model

Zacznijmy od modelu zawierające pola niezbędne do zalogowania.

Moduł

Moduł LoginModule będzie odpowiedzialny za obsługę żądań HTTP związanych z logowaniem.

Kilka słów komentarza do modułu:
Należy pamiętać o zaimportowaniu przestrzeni nazw Nancy.Authentication.Forms gdzie zaimplementowane są metody rozszerzające LoginAndRedirect i LogoutAndRedirect.

Przy wywołaniu tych metod należy pamiętać o podaniu ścieżki przekierowania po poprawnym zakończeniu akcji logowania lub wylogowania. Zwłaszcza w przypadku LoginAndRedirect jest tu pewien haczyk. Trzeci parametr posiada ustawioną wartość domyślną „/” co w wielu przypadkach powoduje, że aplikacja działa poprawnie. Zalecam jednak użycie ścieżki poprzedzonej tyldą np „~/” gdyż w przypadku instalacji aplikacji w wirtualnej ścieżce serwera HTTP przekierowanie bez tyldy nie będzie działać poprawnie.

Do sprawdzenia poprawności hasła użyłem metody VerifyHashedPassword zdefiniowanej w klasie System.Web.Helpers.Crypto. W przypadku powodzenia użytkownik jest przekierowywany powrotnie do strony, z której przybył do formularza logowania. W przypadku błędnego logowania wyświetlany jest ponownie formularz logowania opatrzony komunikatem przechowywanym z zmiennej ViewBag.ErrorMessage.

Widok

Do stworzenia widoku posłużyłem się razorem. Do projektu dodałem plik \Views\Login\Login.cshtml z kodem podanym poniżej. Poza zwykłym formularzem dodane jest tu odwołanie do szablonu Shared/_Layout.cshtml (pamiętamy o użyciu / zamiast \). Wskazałem też klasę bazową dla widoku Nancy.ViewEngines.Razor.NancyRazorViewBase, gdzie LoginModel jest klasą zdefiniowaną powyżej. Ponadto formularz jest wystylizowany pod Twitter Bootstrap.

Koniec wieńczy dzieło

W końcu można przetestować całość dodając żądane autoryzacji do modułu:

Należy pamiętać o dodaniu przestrzeni nazw Nancy.Security, gdyż tam znajduje się metoda rozszerzająca RequiresAuthentication.

Źródła

Błąd w cache Tanka Nancy Optimization

Ostatio w poście napisałem jak łączyć arkusze stylów z użyciem Tanka Nancy Optimization. Podobnie można także robić z plikami javascript. Jednakże Tanka Nancy Optimization framework zawiera pewien błąd, który powoduje zwracanie błędnych pakietów zawierających połączone pliki css lub js.

Jak to? Jak to się stało?

Błąd polega na tym, że połączone i spakowane wiązki są przechowywane w cache, ale klucz do cache jest generowany w dość ubogi sposób i do tego z błędem. Bierze on pod uwagę jedynie czas modyfikacji pliku. Ponadto tworząc FileInfo nie jest brana pod uwagę absolutna ścieżka, co skutkuje pobieraniem własności nieistniejącego pliku, a czas ostatniej modyfikacji pliku, który nie istnieje to 1601-01-01. Wynikiem tego zamieszania jest to, że CacheKey zależy jedynie od ilości plików w wiązce.

Studium przypadku

Podczas migracji projektu z ASP.NET MVC do stworzyłem kilka wiązek:

A następnie użyłem ich w pliku razora:

Zgodnie z oczekiwaniami wynikowy plik HTML zawierał tagi:

Strona jednak nie działała, debugger komunikował brak jquery. Ku mojemu zdziwieniu serwer to samo dla /bundles/modernizr.js jak i dla /bundles/jquery.js.

blad-tanka-modernizr-zamiast-jquery
Analizując genezę problemu potwierdza się, że wszystkie wiązki zawierające po tyle samo plików źródłowych (tutaj słownie po jednym pliku źródłowym) dostają taki sam klucz cache i są nierozróżnialne z punktu widzenia serwera.

Workaround?

Zgłosiłem buga autorowi i trzeba czekać lub poprawić samemu i przekompilować. Najprostsze rozwiązanie typu „przyspawaj mufkę” to tworzenie pakietów zawierających różne ilości plików źródłowych. W razie czego upychamy sianem, czyli tworzymy puste pliki js lub css.Takie rozwiązanie polecam każdemu, kto ma na załatanie 3 minuty i popiera zasadę, że rozwiązania na ślinę i taśmę klejącą są najtrwalsze i najrozsądniejsze :).

Wersja dla twardzieli

Dla tych co chcą poprawić źródła projektu Tanka.Nancy.Optimization podaję 2 skuteczne kroki:

Po pierwsze: w pliku Bundle.cs dokonaj poniższych zmian

Po drugie: do projektu Tanka.Nancy.Optimization dodać klasę o nazwie Startup lub podobnej i poniższej treści:

I po przekompilowaniu i podstawieniu nowych bibliotek cache działa poprawnie.

Powyższe zmiany są dostępne na moim forku projektu https://github.com/isukces/Tanka.Nancy.Optimization.

Wiązanie stylów w NancyFx z użyciem Tanka Nancy Optimization framework

Podczas migracji z ASP.NET MVC do NancyFx napotykamy na problem konieczności dostosowania Razora. Poniżej opisany jest krok po kroku sposób jak aktywować możliwość używania składni wiązania arkuszy CSS znanej z ASP.NET MVC:

 Instalacja Tanka Nancy Optimization framework

Framework ten implementuje funkcjonalność grupowania zarówno arkuszy CSS jak i skryptów JavaScript w wiązki (ang. bundles). Na chwilę obecną ten framework jest dostępny w wersji 0.2.0-beta. Zadziwiająca jest mała ilość pobrać pakietu z Nugeta. Do instalacji należy użyć Nugeta:

Framework jest też dostępny na GitHubie.

Tworzenie pakietów z arkuszy CSS

Definicja pakietu odbywa się poprzez stworzenie klasy dziedziczącej z klasy StyleBundle rezydującej w przestrzeni nazw Tanka.Nancy.Optimization. Oto przykład:

Powyższy kod definiuje wiązkę sklejoną z plików bootstrap.css i dropzone.css udostępnioną pod adresem /Content/css. Jak to bywa w NancyFx większość kodu znajduje się w konstruktorze klasy :). Klasy nie trzeba nigdzie rejestrować; Nancy znajdzie ją sama.

Filozofia wiązania jest zbliżona do tej znanej z ASP.NET MVC, gdzie wykonuje się to mniej więcej tak:

W chwili obecnej możemy już użyć pod razorem składni:

Użycie powyższego kodu spowoduje wygenerowanie na wyjściu razora kodu HTML:

Pamiętamy, że adres nie zawiera tyldy (~) na początku t.j. /Content/css nie zaś ~/Content/css.

Dodanie przestrzeni nazw Tanka.Nancy.Optimization do kompilatora razor

Konieczność podawania pełnej nazwy klasy Tanka.Nancy.Optimization.Styles w kodzie razora nie jest wygodne. Można zatem skonfigurować go tak, aby przestrzeń nazw Tanka.Nancy.Optimization była automatycznie dodawana w trakcie kompilacji strony. W tym celu należy stworzyć klasę implementującą IRazorConfiguration i tam wskazać dodatkową przestrzeń nazw do zaimportowania. Klasa może wyglądać tak:

Tej klasy także nie trzeba nigdzie rejestrować, Nancy i tu znajdzie ją sama. Teraz spokojnie można używać skróconej składni

Odnośniki do źródeł

 Suplement

Radość trwała krótko, ponieważ framework zawiera pewien błąd. Więcej na ten temat w poście Błąd w cache Tanka Nancy Optimization.

Migracje Code Firtst

Po co migracje

Migracje umożliwiają następujące działania na bazie danych

  • zmiana struktury danych (dodawanie/usuwanie tabel, kolumn itp)
  • napełnienie pustej bazy danymi inicjującymi

Włączenie migracji

  1. uruchom komendę Enable-Migrations w Package Manager Console. Pamiętaj aby w polu „Default project” był zaznaczony właściwy projekt.
  2. Jeśli w projekcie jest więcej niż jeden kontekst to trzeba wskazać jego nazwę np.
    Enable-Migrations -ContextTypeName MojProjekt.Models.PricelistContext
  3. Jeśli dodatkowo istniała już wcześniej utworzona klasa migracji t.j. \Migrations\Configuration.cs to należy przemianować nazwę klasy i nazwę pliku a następnie użyć
    Enable-Migrations -ContextTypeName MojProjekt.Models.PricelistContext -Force
    Użycie „Force” bez przemianowania istniejącej klasy po prostu spowoduje jej nadpisanie i utratę wcześniej stworzonego kodu
    Jeśli w projekcie jest więcej niż jeden kontekst to tuż po utworzeniu pliku Configuration.cs zmienić nazwę klasy i pliku.

Aktualizacja bazy danych

Aby dokonać aktualizacji bazy danych t.j. zmienić jej strukturę i/lub napełnić danymi należy wykonać kroki

  1. uruchom komendę Update-database w Package Manager Console. Pamiętaj aby w polu „Default project” był zaznaczony właściwy projekt.
  2. Jeśli w projekcie jest więcej niż jedna klasa konfiguracji migracji to trzeba wskazać nazwę klasy np.
    Update-Database -verbose -ConfigurationTypeName Configuration_Pricelist
  3. Jeśli dodatkowo kontekst danych odnosi się do innej bazy (inny connection string) to należy dodać opcję wskazującą nazwę connection stringa (np. zadeklarowaną w Web.Config) np. -ConnectionStringName PricelistConnectionString

Źródła

Jak dodać użytkowników do pustej bazy

Jak dodać użytkowników do pustej bazy?

Rozwiązanie zaczerpnięte z http://stackoverflow.com/questions/19280527/mvc5-seed-users-and-roles

1. Dodaj poniższą metodę do \Migrations\Configuration.cs oraz jej wywołanie w metodzie Seed.

2. Przekompiluj projekt

3 Uruchom komendę „Update-Database –Verbose” w Package Manager Console. Powinna ona dać wynik mniej więcej taki:

PM> Update-Database –Verbose
Using StartUp project 'MyProjectName’.
Using NuGet project 'MyProjectName’.
Specify the ’-Verbose’ flag to view the SQL statements being applied to the target database.
Target database is: 'aspnet-MyProjectName-20140302072009′ (DataSource: (LocalDb)\v11.0, Provider: System.Data.SqlClient, Origin: Configuration).
No pending explicit migrations.
Running Seed method.

Kluczowa jest ostatnia linijka