wtorek, 29 stycznia 2013

70-516 Tworzenie WCF Data Services - OData

OData to protokół stworzony przez Microsoft, służący przesyłaniu danych za pomocą protokołu HTTP.
Obsługuje następujące metody:

  • GET - selekcja danych (SELECT)
  • POST - wysyłanie danych (INSERT)
  • PUT - uaktualnianie (UPDATE)
  • DELETE - usuwanei danych
Ważnym aspektem jest udzielanie uprawnień dostępu do danych. Możemy przydzielić prawa zarówno na kolekcje zwracane przez serwis jak i operacje, które udostępnia.
Definicja typu wyliczeniowego odpowiadającego za przydział uprawnień:


Code:
  [Flags]
  public enum EntitySetRights
  {
    None = 0, //brak uprawnień do jakichkolwiek operacji
    ReadSingle = 1, //możliwość pobrania tylko jednego elementu z kolekcji
    ReadMultiple = 2, //Możliwość pobrania całej kolekcji
    AllRead = ReadMultiple | ReadSingle, //Odczyt zarówno pojedynczych rekordów jak i całych kolekcji
    WriteAppend = 4,//pozwolenie na dodawanie
    WriteReplace = 8,//pozwolenie na zmianę
    WriteDelete = 16,//pozwolenie na usuwanie
    WriteMerge = 32,//pozwala łączyć dane
    AllWrite = WriteMerge | WriteDelete | WriteReplace | WriteAppend,//wszystkie możliwości manipulacji danymi
    All = AllWrite | AllRead,//wszystkie operacje dozwolone
  }

Aby stworzyć prosty serwis OData postępujemy według instrukcji:
1. Tworzymy nowy projekt ASP.NET
2. Mapujemy za pomocą ORMa np. Entity Framework bazę danych/plik XML który chcemy udostępnić
3. Dodajemy do projektu nowy element typu WCF Data Service:


4. W moim przypadku użyłem bazy danych AdventureWorks. Za pomocą narzędzia Entity Framework Power Tools wygenerowałem model bazy danych i uzyskałem kontekst AdventureWorksLTContext
5. Dodany serwis WCF ma następującą definicję:


Code:
//------------------------------------------------------------------------------
// <copyright file="WebDataService.svc.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;

namespace ODataService
{
    public class AdventureOData : DataService< T >
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        }
    }
}

Aby udostępnić stworzone wersje do odczytu wystarczy w stworzonej klasie zmienić T na typ kontekstu oraz dodać uprawnienia:


Code:
    public class AdventureOData : DataService<AdventureWorksLTContext>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        }
    }

Dodając uprawnienia wprowadziłem gwiazdkę co oznacza iż ustawienie dotyczy wszystkich encji.
Teraz otwieramy przeglądarkę i zmieniamy ustawienie - dla przykładu posłużyłem się przeglądarką IE:


Należy odznaczyć zaznaczoną opcję. Po tej operacji możemy uruchomić naszą aplikację i w pasku przeglądarki wprowadzić adres:



Przykłady zapytań:
Wyciągnięcie klienta o id (klucz główny) = 10 realizujemy zapytaniem: /AdventureOData.svc/Customers(10)
Jeżeli klucz jest łańcuchem znakowym (string) wartość zawieramy w apostrofach, np. Encja('Ala')
Aby pobrać zamówienia klienta o Id 29736 należy użyć właściwości która, prowadzi do encji zamówień:
AdventureOData.svc/Customers(29736)/SalesOrderHeaders
Aby wyświetlić zawartość kolumny imię stosujemy zapytanie: AdventureOData.svc/Customers(29736)/FirstName

Dodatkowe przełączniki wprowadzamy według zapytania: AdventureOData.svc/Customers?$przelacznik
Typy przełączników:

  • $count - zlicza ilość elementów
  • $select=kolumna1,kolumna2 - wyświetla wybrane kolumny
  • $orderby = kolumna1 [desc], kolumna2 [desc] - sortowanie
  • $top=x - wyświetla x rekordów
  • $skip=10&$top=10 - stronicowanie, w takim przypadku warto posortować rekordy, aby dostawać na każdej stronie unikalne wartości
  • $filter - filtrowanie wyniku
  • $expand - wczesne ładowanie (eager loading) - po przecinkach wymieniamy właściwości odpowiadające za nawigację. Jeżeli wymieniona właściwość posiada kolejne referencje do innych encji wymieniamy je po ukośniku "/"
  • $metadata / ?wsdl - schema serwisu
Aby łączyć przełączniki ze sobą kolejne dodajemy po znaku ampersanda - &

Wartości, które można przekazać do filtra:
  • eq - równy
  • ne - nie równy
  • gt - większy od
  • ge - większy bądź równy
  • lt - mniejszy od
  • le - mniejszy lub równy
  • and - operator logiczny "i"
  • or - operator logiczny "lub"
  • Not - zaprzeczenie 
  • Add - matematyczne dodawanie
  • Sub - matematyczne odejmowanie
  • mul - matematyczne mnożenie
  • div - matematyczne dzielenie
  • mod - reszta z dzielenia
  • () - grupowanie wyrażeń
Przykład filtra: /AdventureOData.svc/Customers?$filter=CustomerID gt 10 and CustomerID lt 20

Standard OData oferuje także szereg funkcji umożliwiających na pracę z łańcuchami tekstowymi, datami, czasem, funkcjami matematycznymi oraz typami encji. Spis tych funkcji można znaleźć na stronie http://www.odata.org/documentation/uri-conventions

Brak komentarzy:

Prześlij komentarz