Pokazywanie postów oznaczonych etykietą WCF REST. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą WCF REST. Pokaż wszystkie posty

niedziela, 15 września 2013

Hostowanie serwisu REST, przetwarzanie wiadomości, tworzenie klientów

Aby ułatwić hostowanie serwisów opartych o REST została przedstawiona klasa WebServiceHost. Klasa ta zawiera potrzebne bindingi.
Jedyne co musimy podać to typ serwisu oraz adres pod którym będzie dostępny:


Code:
            var webServiceHost = new WebServiceHost(typeof(Service1), new Uri(@"http://localhost/RestService/"));
            webServiceHost.Open();
            Console.WriteLine("Press key to close");
            Console.Read();
            webServiceHost.Close();


Aby napisać klienta serwisu REST można skorzystać z klasy WebChannelFactory<T>. Kod tworzenia jest wręcz identyczny jak w przypadku połączenia z serwisem SOAP:


Code:
            var webChannelFactory = new WebChannelFactory<IService1>(new Uri("http://localhost/RestService/"));
            var channel = webChannelFactory.CreateChannel();
            List<Person> persons = channel.GetPersons();
            foreach (var person in persons)
            {
                Console.WriteLine("{0} {1}", person.Id, person.Name);
            }



Warto jeszcze w tym miejscu wspomnieć o klasie WebOperationContext. Klasa ta umożliwia dostęp do aktualnie przetwarzanego requestu w metodach serwisu. Możemy dzięki temu pobrać następujące dane:
  • URI wywołania
  • nagłówki 
  • ETag
  • format danych
  • długość wiadomości
Przykładowe wywołanie podczas wykonywania metody serwisu:


Czym jest REST i jak go użyć w WCF

Pisząc o WCF nie sposób pominąć REST. REST (Representational state transfer) - jest wzorcem pisania aplikacji rozproszonych udostępnianych po HTTP. REST zapewnia bardzo dużą skalowalność przez to iż nie jest przechowywany stan pomiędzy żądaniami.
Opiera się o słowa kluczowe dobrze znane z protokołu HTTP: GET, POST, PUT, DELETE. Dane mogą być przesyłane w postaci HTML, XML, JSON.
Wykorzystanie REST jest bardzo szerokie. Wystarczy wymienić, że tacy potentaci jak google, facebook czy flickr udostępniają cześć swojej funkcjonalności właśnie za pomocą REST.

WCF pozwala w bardzo prosty sposób udostępnić serwis jako REST.
Najważniejsza jest poprawna konfiguracja serwisu:


Code:
<?xml version="1.0"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="RestSample.Service1">
        <endpoint address="" binding="webHttpBinding" contract="RestSample.IService1" behaviorConfiguration="sampleBehavior">
        </endpoint>
      </service>
    </services>

    <behaviors>
      <endpointBehaviors>
        <behavior name="sampleBehavior">
          <webHttp helpEnabled="true"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>


Dwie najważniejsze rzeczy jakie musimy wprowadzić do naszego standardowego configu:
  • typ bindingu - webHttpBinding 
  • do behaviors dodajemy webHttp
Co oznacza webHttpBinding i webHttp w przypadku tej konfiguracji?
WebHttpBinding:
  • tworzy kanał Http
  • wprowadza wsparcie dla plików cookie
  • protokoły i bezpieczeństwo (HTTP, HTTPS)
  • kodowanie wiadomości: XML, JSON
WebHttpBehavior:
  • operacje selekcji danych
  • serializacja danych
  • obsługa wywołań

Metody interfejsu możemy oznaczyć dodatkowymi atrybutami:
WebGet:
  • odpowiada czasownikowi HTTP GET
  • pozwala ustawić adres wywołania operacji (UtlTemplate) oraz parametry przekazywane do operacji
  • format wiadomości wyjściowej (XML, JSON)
 WebInvoke
  • pozostałe czasowniki protokołu HTTP
  • domyślnie wywoływany jest POST
  • pozwala na przekazanie parametrów; ostatni parametr wskazuje gdzie ma zostać zdeserializowana zawartość wiadomości
Warto zauważyć jeszcze jeden aspekt przedstawionej konfiguracji - helpEnabled. Dzięki temu przełącznikowi serwis jest w stanie sam wygenerować dokumentację wraz z przykładowymi zapytaniami. Przykładowa konfiguracja wygląda w następujący sposób:




Jest to bardzo przydatne - nie musimy tworzyć własnej dokumentacji - zostaje ona wygenerowana automatycznie.

środa, 11 września 2013

Syndication programming model

Tytuł postu po angielsku - pod taką nazwą łatwiej znaleźć dodatkowe materiały w sieci, a tłumaczenie jej na polski nie przysłużyłoby mi czytelników :)

O co więc chodzi? Syndication programming model to nic innego jak udostępnianie danych w niezależnym formacie. Model ten jest wykorzystywany szczególnie w przypadku blogów. Na pewno każdy spotkał się z terminem kanału RSS. Udostępnienie kanału RSS w przypadku .NET jest niezwykle proste. Framework oferuje dwie gotowe klasy Atom10FeedFormatter oraz Rss20FeedFormatter.

Implementację rozpoczynamy od dodania dwóch atrybutów na interfejs serwisu:


Code:
    [ServiceKnownType(typeof(Atom10FeedFormatter))]
    [ServiceKnownType(typeof(Rss20FeedFormatter))]
    [ServiceContract]
    public interface IService1

Do interfejsu dodajemy metodę odpowiedzialną za generowanie zawartości kanału:


Code:
        [WebGet(UriTemplate = "personsFeed")]
        SyndicationFeedFormatter GetPersonFeed();

Ostatni etap to implementacja metody:

Code:
        public SyndicationFeedFormatter GetPersonFeed()
        {
            var persons = new List<Person>
            {
                new Person {Id = 1, Name = "Patryk"},
                new Person {Id = 2, Name = "Marek"},
                new Person {Id = 3, Name = "Sebastian"},
                new Person {Id = 4, Name = "Ania"}
            };

            var feed = new SyndicationFeed(persons.Select(x => new SyndicationItem(x.Id.ToString(), x.Name, null)));
            string format = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["format"];
            if (!string.IsNullOrWhiteSpace(format) && format.Equals("atom"))
            {
                return new Atom10FeedFormatter(feed);
            }
            return new Rss20FeedFormatter(feed);
        }


Serwis możemy podglądnąć w przeglądarce:






Przykładowy wynik jest bardzo prostym zastosowaniem kanału RSS. Więcej o możliwościach i architekturze RSS można poczytać na stronach msdn.

środa, 12 czerwca 2013

WCF REST Routing

Jeżeli ktoś miał okazję pisać w ASP.NET MVC, z pewnością docenia możliwości jakie daje routing. Dzięki jego zastosowaniu upraszcza się ścieżka prowadząca do żądanych zasobów.
WCF od wersji .NET 4.0 także pozwala na zastosowanie routingu i zastąpienie standardowego Service.svc/zasób ścieżką bardziej przyjazną.

Aby możliwe było użycie routingu w WCF, podobnie jak w przypadku MVC należy dodać plik Global.asax i w nim skonfigurować na starcie nasz serwis:

Code:
        protected void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes();
        }

        private static void RegisterRoutes()
        {
            var webServiceHostFactory = new WebServiceHostFactory();
            RouteTable.Routes.Add(new ServiceRoute("MyService", webServiceHostFactory, typeof(Service1)));
        }


To wszystko co jest wymagane aby routing działał. Teraz w przeglądarce możemy przetestować czy rozwiązanie działa poprawnie.

Standardowe wywołanie:


Wywołanie z zastosowaniem routingu:



Jak widać obie wersje działają. Mechanizm bardzo użyteczny i bardzo dobrze się stało, że został zaimplementowany w WCF REST.

Kod źródłowy przykłądu do pobrania:  http://sdrv.ms/11plYts

wtorek, 11 czerwca 2013

WCF Rest - automatyczne formatowanie odpowidzi

WCF 4.0 wprowadza bardzo fajny dodatek pozwalający na automatyczne formatowanie odpowiedzi w zależności od wartości nagłówka Accept. Już nie trzeba ustawiać na metodzie czy ma zwracać JSON czy też XML. Wystarczy przesłać odpowiednią wartość nagłówka Accep np. text/xml dla XML lub application/json dla JSON.

Aby możliwe były formatowanie w zależności od nagłówka Accept, należy ustawić atrybut automaticFormatSelectionEnabled na wartość "true":

Code:
      <endpointBehaviors>
        <behavior name="web">
          <webHttp automaticFormatSelectionEnabled="true"/>
        </behavior>
      </endpointBehaviors>


Po tym zabiegu możemy przetestować rozwiązanie np. za pomocą Fiddlera:



Odpowiedź:



Jeżeli zmienimy teraz na text/xml:



Otrzymamy odpowiedź:



Tak więc bez dodatkowej pracy możemy formatować odpowiedź do dogodnej dla nas postaci.


Kod źródłowy przykładu: http://sdrv.ms/14okftO