OData Selbst gemacht
Rafael Dabrowski oh22data AG Application Development SharePoint, Nintex, Web-Technologien r.dabrowski@oh22.net
Agenda Warum OData? Was ist OData? Wie erstelle ich einen OData WebService selbst? OData Query Options Wie kann ich OData konsumieren?
Warum OData?
Die Welt früher Ein Datenbank Server Eine Client Software Installiert auf mehreren Endgeräten Nachteile: Endgeräte meist strikt spezifiziert bspw: WindowsXP Keine Schnittstellen nach Außen
Die Welt heute Nicht viel anders ;) Aber die Umwelt hat sich verändert! Arbeiten von Unterwegs, Mobiles und Tablets SelfService BI Wie die neuen Möglichkeiten bedienen?
Was ist OData?
Was ist OData? Web Service Protokoll Von Microsoft entwickelt Unterliegt Open Specification Promise (OSP) Zum Lesen und schreiben von Daten OSP: Versprechen von Microsoft dass die Spezifikation frei benutzt werden kann Nicht mit GPL kompatibel: Zukünftige Versionen ausgeschlossen SourceCode fällt nicht unter OSP
Was ist OData? HTTP basiert Setzt auf offene Technologien auf REST AtomPub JSON +X
Was ist OData?
Was ist OData?
Antwort: AtomPub
Antwort: JSON
Wie erstelle ich ein OData WebService selbst?
Voraussetzungen Visual Studio 2010 oder 2012 IIS Express oder höher WCF Data Services 5.0+ IIS Express oder höher (optional) Datenbank jeglicher Art
Demo Steps: Leeres Web Projekt erstellen EntityFrameWork Model einfügen (ADO.NET Entity Data Model) WCF DataService einfügen WCF DataService 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.Entity.Infrastructure; using System.Data.Objects; using System.Data.Services; using System.Data.Services.Common; using System.Linq; using System.Linq.Expressions; using System.ServiceModel.Web; using System.Web; namespace SqlSaturdayDemoOData { public class AWService : DataService<AdventureWorksLT2012Entities> // This method is called only once to initialize service-wide policies. public static void InitializeService(DataServiceConfiguration config) //Bestimmt die Entitäten und die Zugrifsregeln config.SetEntitySetAccessRule("*", EntitySetRights.AllRead); config.SetEntitySetAccessRule("ProductCategory", EntitySetRights.All); //Bestimmt die eigenen Funktionen config.SetServiceOperationAccessRule("Getproduct", ServiceOperationRights.All); //Bestimmt die OData Version die benutzt wird. config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3; } //Ein QueryInterceptor wird ausgeführt wenn die angegebene Entität abgefragt wird. //Kann für zusätzliches Filtern/Securityzwecke genutzt werden [QueryInterceptor("Product")] public Expression<Func<Product, bool>> OnProductChange() return p => p.SellEndDate == null; //Ein ChangeInterceptor wird ausgeführt wenn versucht wird einen Datensatz zu ändern //Kann für Validierungs und Securityzwecke genutzt werden [ChangeInterceptor("ProductCategory")] public void OnPCChanege(ProductCategory item, UpdateOperations ops) //Wenn Insert if (ops == UpdateOperations.Add) item.rowguid = Guid.NewGuid(); //Wenn Insert oder Update if (ops == UpdateOperations.Add || ops == UpdateOperations.Change) //holen des aktuellen Wertes var oldItem = default(ObjectStateEntry); ((IObjectContextAdapter)this.CurrentDataSource).ObjectContext.ObjectStateManager.TryGetObjectStateEntry(item, out oldItem); item.rowguid = (Guid)oldItem.CurrentValues["rowguid"]; item.ModifiedDate = DateTime.Now; //Eine eigene Funktion die ausgeführt werden sollen. siehe auch: SetServiceOperationAccessRule [WebGet] public Product Getproduct(string name) return CurrentDataSource.Product.First(o => o.Name.StartsWith(name)); Demo
OData Query Options
$top/ $skip/ $inlinecount $top: Begrenzt die Anzahl anzuzeigender Objekte $top=5 $skip: Überspringt die die angegebene Anzahl von Objekten $skip=10 $inlinecount: Gibt Anzahl verfügbarer Objekte mit aus $inlinecount=allpages Optimal für Paging
$orderby Sortiert die Ausgabe nach den angegebenen Kriterium $orderby=Name desc Mehrfachnennung durch Komma trennen Sortieren in Joins möglich: Category/Name
$expand Bindet verknüpfte Objekte direkt ein $expand=Customer Komma Separiert Joins möglich
$select Bestimmt anzuzeigende Felder Minimiert Request Größe $select=ID,OrderDate,Customer/ContactName Mehrfachnennung durch Komma möglich Joins möglich, aber nur mit zugehörigem $expand
$filter Filtert die Ausgabe nach den angegebenen Kriterien $filter=LastName eq ‘Gee‘ or startswith(Firstname,‘A‘) Auch durch Joins filterbar Viele Funktionen vorhanden siehe nachfolgende Tabellen
$filter
$filter
Wie kann ich OData konsumieren?
Wie kann ich OData konsumieren
PowerShell –Simpler OData Request function getOData($url){ return ((Invoke-WebRequest $url).Content | ConvertFrom-Json).d.results } GetCustomers $url = 'http://services.odata.org/Northwind/Northwind.svc/Customers?$format=json' getOData $url | Format-Table ContactName, CompanyName GetCustomerOrders $url = 'http://services.odata.org/Northwind/Northwind.svc/Orders?$orderby=Customer/ContactName&$expand=Customer&$format=json' getOData $url | Format-Table OrderID, OrderDate -GroupBy @{name="Customer";Expression={$_.Customer.ContactName}} getOData $url | Where {$_.Customer.ContactName} -eq 'Mario Pontes' | Format-Table OrderID, OrderDate -GroupBy @{name="Customer";Expression={$_.Customer.ContactName}} GetOrdersFromCustomer $url ="http://services.odata.org/Northwind/Northwind.svc/Order_Details?`$filter=Order/Customer/ContactName%20eq%20‘Alexander Feuer'&`$expand=Product,Order,Order/Customer&`$format=json" getOData $url | Format-Table @{name="Product";expression={$_.Product.ProductName}}, UnitPrice, Quantity, Discount, @{Name='Total'; expression={[double]$_.UnitPrice * $_.Quantity* (1-[double]$_.Discount)}} -GroupBy OrderID FROM XML: $url = 'http://services.odata.org/Northwind/Northwind.svc/Orders?$expand=Customer' ([xml]((Invoke-WebRequest $url).Content)).feed.entry | Select {$_.content.properties.OrderDate.innerText}, {$_.link[1].inline.entry.content.properties.ContactName}
PowerShell –Simpler OData Request
PowerShell – Mit mehreren Seiten function getOData($url, $data = @()){ $res = ((Invoke-WebRequest $url).Content | ConvertFrom-Json) $data += $res.d.results if($res.d.__next -ne $null){ return getOData "$($res.d.__next)&`$format=json" $data }else{ return $data }
Excel Ab Excel 2010 Über PowerPivot DatenFeed einbinden Es werden leider keine Links übernommen – müssen selbst nachgepflegt werden.
Resümee Offener Standard Einfach zu implementieren Selbst auf bestehenden Systemen Überall konsumierbar
Links OData Org: http://www.odata.org Northwind Odata Demo Service: http://services.odata.org/Northwind/Northwind.svc/ WCF DataServices Blog: http://blogs.msdn.com/b/astoriateam/
Vielen Dank Kontakt: Rafael Dabrowski – r.dabrowski@oh22.net