REST and JSON in WCF

26
REST and JSON in WCF It is possible to implement and access REST services in WCF And still doing it object oriented This is a short presentation on how to do it in WCF If you a more detailed presentation, there is one from Mix 09 here , or you can find it in this session’s folder. It takes 75 minutes 1

description

REST and JSON in WCF. It is possible to implement and access REST services in WCF And still doing it object oriented This is a short presentation on how to do it in WCF If you a more detailed presentation, there is one from Mix 09 here , or you can find it in this session’s folder . - PowerPoint PPT Presentation

Transcript of REST and JSON in WCF

Page 1: REST and JSON in WCF

1

REST and JSON in WCF

• It is possible to implement and access REST services in WCF• And still doing it object oriented

• This is a short presentation on how to do it in WCF

• If you a more detailed presentation, there is one from Mix 09 here, or you can find it in this session’s folder.

• It takes 75 minutes

Page 2: REST and JSON in WCF

2

First a common soap service:The data object (really doesn't matter her)using System.Runtime.Serialization;namespace Data{ [DataContract] public class Person { [DataMember] public int Id { get; private set; } [DataMember] public string FirstName { get; set; } [DataMember] public string LastName { get; set; } [DataMember] public int Age { get; set; } public static Person[] GetTestPersons(int num) { Person[] result = new Person[num]; for (int i = 0; i < num; i++) result[i] = new Person { Id=(i+1) , FirstName = ""+(char)('a' + i) , LastName = ""+(char)('A' + i), Age = i * 10 }; return result; } }}

Page 3: REST and JSON in WCF

3

First a common soap service:The interface

using System.ServiceModel;using Data;

namespace WcfRestService{ [ServiceContract] public interface IPersonService { [OperationContract]

Person GetPerson(int id);

[OperationContract] Person[] GetPersons();

}}

Page 4: REST and JSON in WCF

4

First a common soap service:The class

using System;using Data;

namespace WcfRestService{ public class PersonService : IPersonService { Person GetPerson(int id) {

return Person.GetTestPersons(id)[id-1]; } public Person[] GetPersons() { return Person.GetTestPersons(5); //Q&D dev. } }}

Page 5: REST and JSON in WCF

5

First a common soap service:The interesting parts of the config file

<services> <service name="WcfRestService.PersonService">

<endpoint address="" binding="wsHttpBinding"

contract="WcfRestService.IPersonService"> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding"

contract="IMetadataExchange"/> <host> <baseAddresses> <add baseAddress="http://localhost:8732/WcfRestService/"/> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="True"/>

</behavior> </serviceBehaviors>

Page 6: REST and JSON in WCF

6

Enable Rest in the serviceFirst the interface• Add WebGet or WebInvoke attributes to the contract• WebGet handles http GET and WebInvoke handles POST• Unfortunately can only strings be handled as parameters

using System.ServiceModel;using System.ServiceModel.Web;using Data;

namespace WcfRestService{ [ServiceContract] public interface IPersonService { [OperationContract] [WebGet(UriTemplate = "Persons/Id/{id}")] Person GetPerson(string id); //Parameter changed to string [OperationContract] [WebGet(UriTemplate = "Persons")] Person[] GetPersons(); }}

Page 7: REST and JSON in WCF

7

Enable Rest in the serviceThe class• We add a method with the string parameter• Gives the option to use two different interfaces

(left as an exercise)

public class PersonService : IPersonService { public Person GetPerson(string strId) { int id = Convert.ToInt32(strId); return this.GetPerson(id); } public Person GetPerson(int id) { return Person.GetTestPersons(id)[id - 1]; } public Person[] GetPersons() { return Person.GetTestPersons(5); } }

Page 8: REST and JSON in WCF

8

Enable Rest in the serviceThe config file• Add a new endpoint and a new behavior

.... <endpoint address="rest" binding="webHttpBinding"

contract="WcfRestService.IPersonService" behaviorConfiguration="webHttp"/>

....

.... <behaviors>.... <endpointBehaviors> <behavior name="webHttp"> <webHttp/> </behavior> </endpointBehaviors> </behaviors>....

Page 9: REST and JSON in WCF

9

Service can be accessed by the browser

Page 10: REST and JSON in WCF

10

A Rest client

• It is not possible (yet?) for VS to automatically generate a proxy for a service that is not made with the WCF Service template.

• You need an interface with the contract (could be the same as on the server, but not necessary)

• Use the contract to get a reference to an object of a class that implements the interface, which is a proxy

• Use the proxy to call services

The point here is that WCF generates the proxy from the attributtes [...] on the interface. But you have to find and insert the information in the attributes

Page 11: REST and JSON in WCF

11

The client side interfaceConnect methods with url’s using WebGet(UriTemplate)using System.ServiceModel;using System.ServiceModel.Web;using Data;

namespace WcfRestService{ [ServiceContract] public interface IPersonService { [OperationContract] [WebGet(UriTemplate = "Persons/Id/{id}")] Person GetPerson(string id);

[OperationContract] [WebGet(UriTemplate = "Persons")] Person[] GetPersons(); }}

Page 12: REST and JSON in WCF

12

The clientConnect to the service.

using System;using System.ServiceModel.Web;using Data;using WcfRestService;namespace RestClient{ class Program { static void Main(string[] args) { WebChannelFactory<IPersonService> cf =

new WebChannelFactory<IPersonService>(new Uri("http://localhost:8732/WcfRestService

/rest")); IPersonService channel = cf.CreateChannel(); Person[] persons = channel.GetPersons(); foreach (Person p in persons) Console.WriteLine("{0}\r\n{1}", p.FirstName

+" "+p.LastName, p.Age);}}}

From here: Business as usual

Page 13: REST and JSON in WCF

13

Another RESTful application

• Use it now

Page 14: REST and JSON in WCF

14

JSONfrom www.json.org

• JSON (JavaScript Object Notation) is a lightweight data-interchange format.

• It is easy for humans to read and write. • It is easy for machines to parse and generate. • It is based on a subset of the JavaScript Programming Language,

Standard ECMA-262 3rd Edition - December 1999. • JSON is a text format that is completely language independent but

uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others.

• These properties make JSON an ideal data-interchange language.

Page 15: REST and JSON in WCF

15

JSONfrom www.json.org

• JSON is built on two structures:

‒ A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.

‒ An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

• These are universal data structures. Virtually all modern programming languages support them in one form or another.

• It makes sense that a data format that is interchangable with programming languages also be based on these structures.

Page 16: REST and JSON in WCF

16

Examples

From MagicEightBall:{"d":"Is this JSON? Yes"}

From Person example (the GetPersons() service):[{"Age":0,"FirstName":"a","Id":1,"LastName":"A"},{"Age":10,"FirstName":"b","Id":2,"LastName":"B"},{"Age":20,"FirstName":"c","Id":3,"LastName":"C"},{"Age":30,"FirstName":"d","Id":4,"LastName":"D"},{"Age":40,"FirstName":"e","Id":5,"LastName":"E"}]

Page 17: REST and JSON in WCF

17

Extend the person example with JSON

• Two alternatives: ‒ Access it like in Rest‒ Access it like in SOAP (I believe)

Page 18: REST and JSON in WCF

18

1st alternative• We'll use some annotations, therefore we need a new interface,

which is quite similar to the previous one [ServiceContract] public interface IPersonServiceJSON { [OperationContract] [WebGet(UriTemplate = "Persons/Id/{id}",

ResponseFormat = WebMessageFormat.Json)] Person GetPerson(string id);

[OperationContract] [WebGet(UriTemplate = "Persons",

ResponseFormat = WebMessageFormat.Json)] Person[] GetPersons(); }public class PersonService:IPersonService,IPersonServiceJSON{...} //Remember to implement the interface

Page 19: REST and JSON in WCF

19

Add a new endpoint

• Could have reused webhttp, but now it is explicit marked for json

<endpoint address="json" behaviorConfiguration="jsonBehave"

binding="webHttpBinding"

contract="WcfRestService.IPersonServiceJSON"/>...<behavior name="jsonBehave"> <webHttp/></behavior>

Page 20: REST and JSON in WCF

20

How to call it

• Just put in the URL, e.g. http://localhost:8732/WcfRestService/json/persons

• If you do it in the browser you will be asked to save a file. Save it as a txt file. Then you can see it in an editor

Page 21: REST and JSON in WCF

21

2nd alternative• Change the interface and config from 1st alternative to: [ServiceContract] public interface IPersonServiceJSON { [OperationContract] [WebGet] Person GetPerson(string id);

[OperationContract] [WebGet] Person[] GetPersons(); }

<behavior name="jsonBehave"><enableWebScript/>

</behavior>

http://localhost:8732/WcfRestService/json/GetPerson?id=5

Page 22: REST and JSON in WCF

22

Snippets of AJAXFull example in folder

• Get an object for sending server requests<script language="javascript" type="text/javascript"> function makeCall(operation) { var xmlHttp; try { xmlHttp = new XMLHttpRequest(); } catch (e) { try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("This sample only works in browsers with AJAX"); return false; } } }

Page 23: REST and JSON in WCF

23

React when state changes in http

xmlHttp.onreadystatechange = function() { if (xmlHttp.readyState == 4) { //Finished receiving if (xmlHttp.status == 200) { //Response: OK

//Get the response (result) var result = eval('(' + xmlHttp.responseText + ')');

//Unsafe way of evaluating JavaScript. It can be injected document.getElementById("result").innerHTML = result.d; } else alert(xmlHttp.status); //Not OK document.getElementById("jsonText").innerHTML =

xmlHttp.responseText; } }

Page 24: REST and JSON in WCF

24

Send request with get or post

var url = "http://localhost:8080/MagicEightBallService/json/"; url = url + operation;

var params = '{"userQuestion":"'; params = params + document.getElementById("question").value; params = params + '"}';

if (readRadioButton("MethodRadio")=="GET") url=url+"?userQuestion="

+document.getElementById("question").value; xmlHttp.open(readRadioButton("MethodRadio"), url, true); xmlHttp.setRequestHeader("Content-type", "application/json"); xmlHttp.send(params); }

Page 26: REST and JSON in WCF

26

Exercise (optional)

• Make a web service for the bank.• Start by making a soap based ws.• And then add a rest based