Programmeren in ASP.NET/Webservices
Wat zijn webservices?
[bewerken]XML-webservices of kortweg webservices zijn diensten die de ene website kan aanbieden en die door een andere website (of door een ander programma) gebruikt of "geconsumeerd" kunnen worden. Je kan je een webservice voorstellen als een functie die je kan aanroepen vanaf een andere website.
Wat deze functies kunnen doen is in feite onbegrensd. Voorbeelden zijn:
- het boeken van een hotel
- het lezen van mail
- het vertalen van tekst
- het controleren of een mailadres van een spammer is
- het opvragen van de weersituatie op een bepaalde plaats
- enzovoort...
Hierdoor wordt het mogelijk verschillende websites te laten samenwerken door elkaar informatie te leveren. Jouw website kan een onderdeel tonen met gegevens die door een webservice in Amerika geleverd wordt. Omgekeerd kan jouw website ook een dienst leveren die door andere sites gebruikt wordt.
Er wordt verwacht dat webservices in de toekomst steeds belangrijker zullen worden. Microsoft heeft als demonstratie een site www.live.com die volledig gebaseerd is op webservices.
Het dotNET-framework heeft ingebouwde ondersteuning voor het maken en openstellen van webservices op een manier die gemakkelijk kan gebruikt worden door programmeurs.
ASP.NET ondersteunt verschillende gegevenstypes voor webservices. Je kan zelfs volledige databanktabellen doorgeven met een webservice in de vorm van een DataSet.
XML-webservices aanbieden met ASP.NET
[bewerken]ASP.NET ondersteunt XML-webservices door middel van een .asmx-bestand. Een .asmx-bestand is een tekstbestand vergelijkbaar met een .aspx-bestand, maar het bevat alleen code en geen HTML. Dit bestand kan onderdeel zijn van een ASP.NET-applicatie waarin ook .aspx-bestanden zitten. Je kan dit bestand opvragen met de browser, net zoals .aspx-bestanden. Maak een nieuw bestand in Visual Studio, maar kies als type niet Web Form, maar wel Web Service. Je krijgt een asmx-bestand. Pas het aan zodat je dit resultaat krijgt:
helloworld.asmx
<%@ WebService Language="VB" Class="helloworld" %> Imports System.Web Imports System.Web.Services Imports System.Web.Services.Protocols <WebService(Namespace := "https://tempuri.org/")> _ <WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _ Public Class helloworld Inherits System.Web.Services.WebService <WebMethod()> _ Public Function SayHelloWorld() As String Return "Hello World" End Function End Class
Dit bestand begint met een ASP.NET-directief WebService, en stelt de taal in op C#, Visual Basic, of JScript. Vervolgens importeert het de naamruimte System.Web.Services. Dit is verplicht.
Dan wordt de klasse HelloWorld gedeclareerd. Deze klasse is Public, en afgeleid van de basisklasse WebService, maar dit is optioneel. Voor elke webservice moet je zo’n klasse aanmaken. Deze klasse kan allerlei methodes bevatten, maar alle methodes die als webservice toegankelijk moeten zijn moeten een extra attribuut <WebMethod()> hebben. Zonder dit attribuut is de methode niet toegankelijk van buitenaf.
Om deze webservice nu toegankelijk te maken noem je het bestand HelloWorld.asmx en je plaatst het op een server mijndomein.com binnen een virtuele folder mijnfolder.
Met een browser kan je nu de URL https://mijndomein.com/mijnfolder/HelloWorld.asmx intikken, en de pagina die je dan krijgt zal de publieke methodes voor deze XML-webservice tonen (de methodes die het WebMethod-attribuut hadden). Verder kun je ook zien welke protocollen (zoals SOAP, of HTTP GET) gebruikt kunnen worden om deze methodes aan te roepen. Let op: veel publieke webservices schermen deze testmogelijkheid af.
Als je daarentegen het adres: https://mijndomein.com/mijnfolder/HelloWorld.asmx?WSDL (hetzelfde adres met ?WSDL erachter) in de browser intikt, dan krijg je een zogenaamd Web Service Description Language (WSDL) document. Dit WSDL-document is erg belangrijk, en het wordt door clients gebruikt om informatie te krijgen over de webservice.
Hieronder zal je leren hoe je die informatie in je webpagina's kan gebruiken.
XML-webservice-bestanden worden onder ASP.NET bewaard met de extensie asmx. Net zoals aspx-bestanden worden deze automatisch de eerste keer gecompileerd naar een DLL door de ASP.NET-runtime als ze opgevraagd worden, en daarna wordt de gecompileerde versie gebruikt voor nieuwe aanvragen.
Nota: XML-webservices zijn een algemene Internet-standaard. Ze hoeven daarom niet noodzakelijk met ASP.NET gemaakt te zijn. Wees dus niet verwonderd als je nergens een asmx-bestand ziet. Meestal vind je wel in de documentatie hoe je de service dan moet opvragen.
XML-webservices consumeren
[bewerken]ASP.NET heeft niet alleen de technologie om XML-webservices aan te bieden, maar ook een aantal tools en code om webservices te consumeren. Omdat webservices gebaseerd zijn op open protocollen zoals het Simple Object Access Protocol (SOAP) kun je met ASP.NET ook webservices gebruiken die helemaal niet met ASP.NET gemaakt zijn.
Om de webservice hierboven te gebruiken (te "consumeren"), moet je een zogenaamde proxy-klasse aanmaken. De proxy-klasse is een DLL die de webservice lokaal zal vertegenwoordigen, en die dan gebruikt kan worden om de webservice aan te spreken. Je kunt deze DLL daarna gebruiken in je aspx-pagina's.
Voorbeeld 1
[bewerken]Hier zullen we de “Hello World”-service consumeren.
In Visual Web Developer klik je rechts op je project in de Solution Explorer, en je kiest "Add Web Reference..." (of: "Add Service Reference" in Express for Web). Vul het adres in van je asmx-bestand en klik op "Go".
Verander de "Web reference name" in "NSHello" en klik op de knop "Add Reference".
Er wordt een nieuwe subfolder App_WebReferences aangemaakt. Hierin verschijnen drie bestanden: helloworld.disco, helloworld.discomap en helloworld.wsdl. Deze bestanden worden gebruikt door ASP.NET om informatie te vinden over de webservice.
Wanneer je daarna een methode van de klasse aanroept, dan zal dit ervoor zorgen dat de proxy-klasse een SOAP-verzoek stuurt naar de webservice. Er komt vervolgens een SOAP-antwoord terug, en dit wordt in dit geval vertaald naar een string.
Vanuit het standpunt van de client zal de code heel simpel zijn:
HelloWorld7.aspx
<%@ Page Language="VB" %> <script runat="server"> Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Dim mijnHelloWorld As New NSHello.helloworld() Label1.Text = mijnHelloWorld.SayHelloWorld() End Sub </script> <html xmlns="https://www.w3.org/1999/xhtml" > <head runat="server"> <title>Een eenvoudige webservice</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" /> <asp:Label ID="Label1" runat="server" ></asp:Label> </div> </form> </body> </html>
Het resultaat is een label met "Hello World".
Voorbeeld 2
[bewerken]Hier is nog een voorbeeld van een webservice, genaamd RekenService, die enkele methodes aanbiedt voor het optellen, aftrekken, delen en vermenigvuldigen van twee getallen. Elke methode heeft het <WebMethod()>-attribuut.
RekenService.asmx
<%@ WebService Language="VB" Class="RekenService" %> Imports System Imports System.Web.Services Public Class RekenService : Inherits WebService <WebMethod()> Public Function Telop(A As Integer, B As Integer) As Integer Return A + B End Function <WebMethod()> Public Function Trekaf(A As Integer, B As Integer) As Integer Return A - B End Function <WebMethod()> Public Function Vermenigvuldig(A As Integer, B As Integer) As Integer Return A * B End Function <WebMethod()> Public Function Deel(A As Integer, B As Integer) As Integer If B = 0 Then Return -1 // return 'null' (-1 is ook -n/n en een geldig antwoord) Bij fouten een willekeurig antwoord retourneren is heel gevaarlijk. Net als '999999' e.d. Return Convert.ToInt32(A / B) End Function End Class
Merk op dat één webservice dus meerdere methodes kan bevatten.
Dit is een voorbeeld hoe je deze webservice kan consumeren:
''RekenService.aspx'' <%@ Page Language="VB" %> <%@ Import Namespace="NSRekenService" %> <script language="VB" runat="server"> Dim Op1 As Integer = 0 Dim Op2 As Integer = 0 Public Sub Submit_Click(Sender As Object, E As EventArgs) Op1 = CInt(Operand1.Text) Op2 = CInt(Operand2.Text) Dim Service As New NSRekenService.RekenService() Select (CType(sender,Control).ID) Case "Telop" : Result.Text = "Resultaat = " & Service.Telop(Op1, Op2).ToString() Case "Trekaf" : Result.Text = "Resultaat = " & Service.Trekaf(Op1, Op2).ToString() Case "Vermenigvuldig" : Result.Text = "Resultaat = " & Service.Vermenigvuldig(Op1, Op2).ToString() Case "Deel" : Result.Text = "Resultaat = " & Service.Deel(Op1, Op2).ToString() End Select End Sub </script> <html> <head> <title> Een simpele Reken Service </title> </head> <body> <form runat="server"> Operand 1:<br><asp:TextBox id="Operand1" Text="15" runat="server"/><br> Operand 2:<br><asp:TextBox id="Operand2" Text="5" runat="server"/><p> <input type="submit" id="Telop" value="Telop" OnServerClick="Submit_Click" runat="server"> <input type="submit" id="Trekaf" value="Trekaf" OnServerClick="Submit_Click" runat="server"> <input type="submit" id="Vermenigvuldig" value="Vermenigvuldig" OnServerClick="Submit_Click" runat="server"> <input type="submit" id="Deel" value="Deel" OnServerClick="Submit_Click" runat="server"> <p> <asp:Label id="Result" runat="server"/> </form> </body> </html>
Merk op dat RekenService.asmx en RekenService.aspx op verschillende servers zullen staan.
Voorbeeld 3
[bewerken]Een voorbeeld dat tot de verbeelding spreekt is het opvragen van het weer.
Op: https://www.webservicex.net/globalweather.asmx?op=GetWeather kan je het weer opvragen voor een groot aantal steden over heel de wereld.
Voeg eerst een web-referentie NSWeer toe van het adres: https://www.webservicex.net/globalweather.asmx?wsdl
Gebruik dan deze pagina om de service te testen (verander indien nodig de namespace):
Weer.aspx
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> Sub Button1_Click(sender As Object, e As EventArgs) Dim service As New NSWeer.GlobalWeather() Dim Output As String = service.GetWeather(tbStad.Text, tbLand.Text) Label1.Text = Output End Sub </script> <html xmlns="https://www.w3.org/1999/xhtml" > <head runat="server"> <title>Weer</title> </head> <body> <form id="Form2" runat="server"> Stad: <asp:TextBox id="tbStad" runat="server"></asp:TextBox> <br> Land: <asp:TextBox id="tbLand" runat="server"></asp:TextBox> <br> <asp:Button id="Button1" onclick="Button1_Click" runat="server" Text="Toon het weer"></asp:Button> <br> <asp:Label id="Label1" runat="server"></asp:Label> </form> </body> </html>
UDDI
[bewerken]Er bestaat een soort "telefoonboek" voor webservices. Hiervoor gebruikt men een speciaal protocol: UDDI. Dit staat voor Universal Description, Discovery and Integration.
Zoekmachines voor webservices zijn https://www.xmethods.net, https://www.remotemethods.com en https://www.webservicex.net.
Oefeningen
[bewerken]- Maak een webservice die van een gegeven temperatuur in °C de overeenkomstige temperatuur in °F teruggeeft. Maak ook een pagina waarin de webservice gebruikt wordt.
- Maak een webservice die van een gegeven land de hoofdstad opzoekt in een kleine databank. Maak ook een pagina waarin de webservice gebruikt wordt.
- Maak een webservice die van een gegeven gemeente de postcode opzoekt. Maak ook een pagina waarin de webservice geconsumeerd wordt.
- Maak een pagina die gebruik maakt van de webservice op https://www.kamalpatel.net/ConvertCSharp2VBService.asmx om C#-code om te zetten in VB-code.
- Maak een pagina die gebruik maakt van de webservice op https://www.webservicex.com/sendsmsworld.asmx om een SMS te sturen naar bepaalde landen.