czwartek, 29 sierpnia 2013

[C#|Visual Studio] ServiceStack: Filtry

Filtrami w ServiceStacku nazywane są fragmenty kodu wywoływane przed lub po każdym zapytaniu. Można ustawiać im priorytety, które odpowiadają później kolejności, w jakiej filtry się wykonują. Aby stworzyć filtr wystarczy dziedziczyć po klasie RequestFilterAttribute lub ResponseFilterAttribute.

public class IpRecordFilter : RequestFilterAttribute
{
    public ICacheClient Cache { get; set; }

    public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto)
    {
        Cache.Add(req.UserHostAddress, req.RemoteIp);
    }
}

Użycie filtra sprowadza się do dodania atrybutu nad DTO lub serwisem.

public class EntryService : Service
{
    public int Sum { get; set; }

    [IpRecordFilter]
    public object Post(Entry entry)
    {
        Sum += entry.Count;
        return new EntryResponse() {Total = Sum};
    }
}

środa, 28 sierpnia 2013

[C#|Visual Studio] ServiceStack: Autentykacja i autoryzacja

Proces autentykacji ma na celu potwierdzenie tożsamości użytkownika, natomiast autoryzacja ma na celu wertfikację uprawnień użytkownika. W Service Stacku obie funkcjonalności zostały zaimplementowane w prosty sposób. Zaczynamy od modyfikacji w pliku Global.asax

public override void Configure(Funq.Container container)
{
    Plugins.Add(new AuthFeature( () => new AuthUserSession(), 
        new IAuthProvider[]
        {
            new BasicAuthProvider()
        }));

    Plugins.Add(new RegistrationFeature());

    container.Register<ICacheClient>(new MemoryCacheClient());
    var userRepository = new InMemoryAuthRepository();
    container.Register<IUserAuthRepository>(userRepository);
}

Skonfigurowany został jeden z gotowych providerów, BasicProvider. Programiści mają też możliwość definiowania własnych providerów. RegistrationFeature umożliwi REST-owe definiowanie ról. Repozytorium pacjentów trzymane będzie w pamięci. W tym samym miejscu możemy dodać pierwszego użytkownika z rolą Admin

string hash, salt;

new SaltedHash().GetHashAndSaltString("password", out hash, out salt);
userRepository.CreateUserAuth(new UserAuth()
                                  {
                                      Id = 1,
                                      FirstName = "John",
                                      Email = "jdoe@gmail.com",
                                      PasswordHash = hash,
                                      UserName = "jdoe",
                                      LastName = "Doe",
                                      Salt = salt,
                                      Roles = new List<string>(){RoleNames.Admin},
                                      Permissions = new List<string>(){"GetEntry"}
                                  }, "password");

Wymagane role i uprawnienia a także konieczność autentykacji deklarujemy atrybutami.

[Route("/entry")]
[Authenticate]
[RequiredRole("User")]
public class Entry : IReturn<EntryResponse>
{
    public DateTime Date { get; set; }
    public int Count { get; set; }
}

Logowanie i przydzielanie ról użytkownikom (w szczególnym przypadku samemu sobie) wykonuje się w poniższy sposób

var client = new JsonServiceClient("http://localhost:51270"){UserName = "jdoe", Password = "password"};
client.Send<AssignRolesResponse>(new AssignRoles()
                                     {
                                         UserName = "jdoe",
                                         Roles = new List<string>(){"User"},
                                         Permissions = new List<string>(){"GetEntry"}
                                     });

niedziela, 25 sierpnia 2013

[C#|Visual Studio] ServiceStack: Klient C#

Restowe API można łatwo odpytywać z kodu w C#. Wystarczy dodać nowy projekt w Visual Studio, który będzie zawierał referencję do projektu serwerowego. W klienckim projekcie należy też doinstalować .dll ServiceStack.Text. Jeżeli klientem ma być np. aplikacja konsolowa, to trzeba także przełączyć wersję .NET na np. 4.0 (bez Client Profile).


Z uwagi na wygodę po stronie klienckiej, obiekty DTO należy pisać w poniższy sposób:

[Route("/entry")]
public class Entry : IReturn<EntryResponse>
{
    public DateTime Date { get; set; }
    public int Count { get; set; }
}

public class EntryResponse
{
    public int Total { get; set; }
    public ResponseStatus ResponseStatus { get; set; }
}

a więc tak, aby implementować interfejs IReturn<T> oraz w obiektach typu T zamieszczać ResponseStatus, gdzie automatycznie zostanie wstawiony kod błędu.

Samo wywołanie serwisu po stronie klienckiej można wykonać synchronicznie lub asynchronicznie, np.

var client = new JsonServiceClient("http://localhost:51270");

var response = client.Send(new Entry() {Count = 12});
Console.WriteLine(response.Total);

client.SendAsync(new Entry() { Count = 24 }, 
    resp => Console.WriteLine(resp.Total),
    (err,exc) => Console.WriteLine("error"));

Odpowiedź zostanie zdeserializowana do odpowiedniego typu.w przypadku obu wywołań. Nie trzeba podawać większej ilości parametrów, gdyż wszystkie są pobierane z obiektów DTO (route i typ zwracany). JsonServiceClient można wymienić na inne typy klienckie, takie jak: JsvServiceClient czy CsvServiceClient

piątek, 23 sierpnia 2013

[C#|Visual Studio] ServiceStack: Tworzenie WebSerwisów

W tym poście zostanie opisane, jak utworzyć prosty projekt z RESTowymi serwisami w oparciu o ServiceStacka. Zaczynamy od stworzenia w Visual Studio pustego projektu ASP .NET.


Następnie za pomocą NuGeta instalujemy dllki ServiceStack.


Następnie tworzymy proste obiekty DTO, do których serializowane i deserializowane będą responsy i requesty REST-owe. Dobrą praktyką jest, aby obiekty DTO były symetryczne i przez konwencję do nazwy obiektu zwrotnego dodajemy "Response".

[Route("/entry/{Date}", "GET")]
public class Entry
{
    public DateTime Date { get; set; }
    public int Count { get; set; }
}

public class EntryResponse
{
    public int Total { get; set; }
}

Poprzez atrybuty definiujemy routingi, w których fragmenty ścieżek można bindować bezpośrednio do properties DTO. Następnie dodajemy klasę serwisu, która dziedziczy po bazowej klasie Service z SeriveStack. W klasie dodajemy metody o takich nazwach jak czasowniki HTTP, gdzie parametrem będzie zdefiniowane wcześniej DTO.

public class EntryService : Service
{
    public int Sum { get; set; }

    public object Post(Entry entry)
    {
        Sum += entry.Count;
        return new EntryResponse() {Total = Sum};
    }
}

Aby wystartować serwis, wystarczy skorzystać z pliku .asax.

public class Global : System.Web.HttpApplication
{

    public class MyEntryAppHost : AppHostBase
    {
        public MyEntryAppHost()
            : base("MyEntryService", typeof(EntryService).Assembly)
        {
        }

        public override void Configure(Funq.Container container)
        {
            
        }
    }

    protected void Application_Start(object sender, EventArgs e)
    {
        new MyEntryAppHost().Init();
    }
    //...
}

Metoda Configure posłuży jako bootstrapper, gdzie będzie można konfigurować np. kontener IoC. Ostatnim etapem jest skonfigurowanie pliku Web.config, gdzie dodajemy odpowiedni handler.

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>

  <system.web>
    <httpHandlers>
      <add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*"/>
    </httpHandlers>
  </system.web>

</configuration>

Po uruchomieniu aplikacji mamy możliwość podglądu i testowania naszych endpointów.

wtorek, 20 sierpnia 2013

[C#|Visual Studio] ServiceStack: Wprowadzenie

ServiceStack to framework będący alternatywą dla WCF, WebAPI czy MVC. Jedną z głównych zalet jest cross - platformowość. Autorem Service Stacka nie jest Microsoft, ale community, które udostępnia go na zasadzie open source. Co więcej aplikacje pisane w ServiceStack nie muszą być hostowane na IIS, można je kompilować na Mono i uruchamiań np, na Linuxie.

Nazwa ServiceStack ma symbolizować stos technologii, na jakich budowane są aplikacje.


Kolejnymi względami przemawiającymi za tą technologią są prostota w stosunku do innych frameworków (w ServiceStack mamy do czynienia z konwencjami, które eliminują sporo zbędnych konfiguracji), oraz wydajność poszczególnych komponentów w porównaniu z alternatywnymi technologiami, głównie narzędzia ORM, kontenera IoC, serializator JSON.

W Visual Studio Service Stack instalujemy za pomocą NuGeta.

Przy instalacji do projektu załączane są dodatkowe .dll - ki, takie jak Text (serializacja JSON), Redis (api .NET do bazy NoSql), OrmLite (mapper obiektowo relacyjny).

Web Serwisy pisane w ServiceStacku bazować mają na Data Transfer Objects. Ideę DTO przedstawia poniższy rysunek

Parametrem każdego requestu jest prosty obiekt DTO mający ustawione odpowiednie pola. Jeżeli np. chcemy odpytywać jakąś kolekcję po różnych parametrach, to ustawiamy w danym momencie ten, który nas interesuje w obiekcie DTO.

Strona ServiceStack: http://www.servicestack.net

niedziela, 18 sierpnia 2013

[HTML|JS|CSS] CSS3: calc

Calc to funkcja, która umożliwia przeliczanie różnych jednostek długości w stylach CSS. Wsparcie dla calc dostarcza coraz więcej przeglądarek, niektóre wymagają jeszcze użycia tzw. vendor prefixes.


Przykład użycia calc w Sassie:

@mixin calc($property, $expression) { 
  #{$property}: -moz-calc(#{$expression}); 
  #{$property}: -o-calc(#{$expression}); 
  #{$property}: -webkit-calc(#{$expression}); 
  #{$property}: calc(#{$expression}); 
} 

.outer{
 width: 100%;
 background-color: red;
 height: 100px;
}

.inner{
 @include calc("width","100% - 200px");
 background-color: blue;
 height: 100px;
}

Szerokość wewnętrznego diva będzie przeliczana przy każdej zmianie rozmiaru okna.

.outer {
  width: 100%;
  background-color: red;
  height: 100px; }

.inner {
  width: -moz-calc(100% - 200px);
  width: -o-calc(100% - 200px);
  width: -webkit-calc(100% - 200px);
  width: calc(100% - 200px);
  background-color: blue;
  height: 100px; }

Pozostaje pytanie, co w przypadku, gdy przeglądarka nie obsługuje calc. Do tego, by wykryć, czy przeglądarka wspiera calc wystarczy znana biblioteka Modernizr od wersji 2.6. Samo przeliczenie wystarczy wykonać w JS np. odejmując od szerokości parenta zadaną powyżej szerokość 200px. .

sobota, 17 sierpnia 2013

[HTML|JS|CSS] Wprowadzenie do TypeScript

TypeScript to język stosunkowo nowy (wprowadzony w drugiej połowie 2012 roku), opracowany przez Microsoft i pana Hejlsberga, mocno kojarzonego z językiem C#. TS ma być rozszerzeniem JavaScriptu wprowadzającym pewne znane z języków obiektowych konstrukcje. Pliki o rozszerzeniu .ts kompilowane są przez kompilator TypeScript do czystego JavaScriptu. Produktem, który idzie w parze z nowym językiem, jest Visual Studio 2012, ale sam kompilator jest darmowy i można go pobrać na przykład menadżerem pakietów Node'a, wpisując polecenie:

npm install typescript

Pliki TypeScript kompilujemy z linii poleceń komendą tsc, na przykład polecenie:

tsc sample.ts

utworzy plik o nazwie sample.js lub (oraz) wypisze błędy składniowe na konsoli.
A oto, co więcej poza czystym JavaScriptem daje programistom TypeScript:

  • Klasy i typowalność
Klasy wprowadzają pewną strukturyzację kodu, co jest nieco utrudnione w JS, gdzie obiektami są funkcje. Typowalność z jednej strony zapewnia walidację, z drugiej podpowiadanie składni w VS 2012. Przykład:


//1. classes

class Customer {
    customerId: number;
    companyName: string;
    contactName: string;
    country: string;

    addCustomer(): number {
        return 0;
    }
}

var cust = new Customer();
cust.companyName = "Google";

i wynik kompilacji:

//1. classes
var Customer = (function () {
    function Customer() {
    }
    Customer.prototype.addCustomer = function () {
        //some code here
        return 0;
    };
    return Customer;
})();

var cust = new Customer();
cust.companyName = "Google";

  • Modyfikatory dostępu
Properties w TS mogą być prywatne lub publiczne (domyślnie). Podobnie jak np, w C# do prywatnych nie mamy dostępu spoza klasy. Próba przypisania wartości spowoduje błąd kompilacji. Modyfikatory dostępu wpływają też na to, które properties w VS podpowiada nam IntelliSense.

//2. Access modifiers

class Employee {
    private customerId: number;
    public companyName: string;
    public contactName: string;
    private country: string;

    getEmployeeId(): number{
     return this.customerId;
    }
}

var emp = new Employee();
emp.companyName = "Google";
//error: 'Employee.country is inaccessible'
//emp.country = "USA";


  • Konstruktory, statyczne properties
Wszystko działa dokładnie tak, jak w językach statycznie typowanych.


//3. Constructors, static members

class Person {
    public personId: number;
    public firstName: string;
    public lastName: string;
    static totalPeople: number;

    constructor(){
     Person.totalPeople = Person.totalPeople + 1;
     this.personId = Person.totalPeople;
    }
}

Person.totalPeople = 0;
var p1 = new Person();
var p2 = new Person();
console.log(Person.totalPeople); //2


  • Dziedziczenie
Dziedziczenie, czyli większa reużywalność kodu,


//4. Inheritance

class Driver extends Person{
 public carMake: string;

 constructor(make: string){
  this.carMake = make;
  super();
 }

 getId(): number{
  return this.personId;
 }
}

var dr1 = new Driver("Ford Fiesta");
console.log(dr1.getId());

Ponadto mamy możliwość definiowania interfejsów (słowa kluczowe inteface i implements), odpowiadających interfejsom z C# oraz modułów (słowo kluczowe module) odpowiadających przestrzeniom nazw w C#.

sobota, 10 sierpnia 2013

[C#|Visual Studio] Regex

W tym poście przedstawione zostaną podstawowe przypadki użycia klasy System.Text.RegularExpressions.Regex. Najprostszy sposób użycia, to sprawdzenie, czy tekst zawiera dany ciąg znaków z opcją CaseSensitive lub bez niej.

var bloodBrothers = new string[]
                           {
                               "And if you're taking a walk through the garden of life",
                               "What do you think you'd expect you would see?",
                               "Just like a mirror reflecting the moves of your life",
                               "And in the river reflections of me",

                               "Just for a second a glimpse of my father I see ",
                               "And in a movement he beckons to me",
                               "And in a moment the memories are all that remain",
                               "And all the wounds are reopening again"
                           };

            var pattern = "and";

            foreach (var s in bloodBrothers)
            {
                if(System.Text.RegularExpressions.Regex.IsMatch(s, pattern, RegexOptions.IgnoreCase))
                {
                    Console.WriteLine(s);
                }
            }

Wszystkie stringi rozpoczynające się od danego ciągu znaków:

pattern = "^(And in a).*";

Wszystkie stringi kończące się na danym ciągu znaków:

pattern = "life$";

Wyrazy dłuższe niż 10 znaków:

pattern = "[A-Z|a-z]{10,}";

Numery telefonu, oddzielone znakiem "-" rozpoczynające się od 3 cyfr a kończące na czterech ([0-9] i \d są równoważne)

pattern = "^([0-9]{3})-.*-\\d{4}$";

Trzy takie same cyfry (nawiasy oznaczają grupę,do której następnie odwołujemy się poprzez \1 z krotnością 2, pytajnik oznacza opcjonalność danego znaku)

pattern = "-?(\\d)(\\1){2}-";

Negacja - wszystkie linie nie zaczynające się od A

pattern = "^[^A]";

Skróty znakowe:




Białe spacje i granice wyrazu:

pattern = "\\bdo\\b\\s\\byou\\b";

Case - insensitive z poziomu wzorca:

pattern = "(?i)what";

Linie zakończone pytajnikiem (przy użyciu Unicode)

pattern = "\\u003F$";

Kwantyfikatory:


Lookaheads i lookbehinds:

pattern = "(?=[a-z]{2} life).{2}";

Pattern taki poszuka wszystkich dwuliterowych napisów, po których w dowolnym miejscu w tekście występuje słowo life. Wzorzec ma zerową długość, a więc ostatnia instrukcja {2} oznacza, że wybrane zostaną właśnie te dwuliterowe wyrazy. Pozostałe możliwości to:

  • ?! - negative lookahead
  • ?<=  - lookbehind 
  • ?<! - negative lookbehind

wtorek, 6 sierpnia 2013

[C#|Visual Studio] LINQ to XML

LINQ to XML, jak nazwa wskazuje umożliwia wykonywanie zapytań LINQ na plikach XML wczytywanych do pamięci za pomocą klasy XDocument. Przykładowy plik XML:

<?xml version="1.0" encoding="utf-8" ?>
<peaks>
  <peak>
    <name>Rysy</name>
    <height unit="mnpm">2499</height>
  </peak>
  <peak>
    <name>Swinica</name>
    <height unit="mnpm">2301</height>
  </peak>
  <peak>
    <name>Kasprowy Wierch</name>
    <height unit="mnpm">1987</height>
  </peak>
  <peak>
    <name>Szpiglasowy Wierch</name>
    <height unit="mnpm">2172</height>
  </peak>
</peaks> 

Plik taki możemy odpytywać przy użyciu zapytań LINQ, np.:

//Queries
XDocument xmlDocument = XDocument.Load("tatra.xml");

var twoThousand = from peak in xmlDocument.Root.Elements("peak")
                  let height = int.Parse(peak.Element("height").Value)
                  where height > 2000
                  select peak.Element("name").Value;

foreach (var peak in twoThousand)
    Console.WriteLine(peak);

LINQ to XML to nie tylko odczyt, ale także wygodna możliwość modyfikacji. Aby dodać nowy szczyt wystarczy skorzystać z klasy XElement, dla której jednym z argumentów jest params umożliwiający budowanie drzewa. Przykład poniżej:

//Modifying
var peaks = xmlDocument.Root;
peaks.Add(new XElement("peak", new XElement("name", "Zawrat"),
                       new XElement("height", new XAttribute("unit", "mnpm"), 2159)));

xmlDocument.Save("tatra2.xml");


Również usuwanie elementów jest bardzo proste.

//Deleting
var highest =
    peaks.Elements("peak").OrderByDescending(x => int.Parse(x.Element("height").Value))
    .FirstOrDefault();
highest.Remove();

xmlDocument.Save("tatra3.xml");