1. Problem
You want to create an
application that interacts with a Representational State Transfer
(RESTful) service that returns a response in JavaScript Object Notation
(JSON) format.
2. Solution
You must use WebClient and DataContractJsonSerializer.
3. How It Works
WebClient provides
common methods for sending and receiving data to and from a resource
identified by a URI. In this case, the resource will give you a response
in JSON format. Then you will use DataContractJsonSerializer to deserialize the response inside your object graph.
4. The Code
For the purposes of this
exercise, you will use an API made available by Google for the
translation of texts. (To use this API, you must have a key to access
the service itself).
The application that you
will create in terms of the UI is quite simple. It will have a text box
for entering text to be translated, a button to start the interaction
with the service, and a text block to show the result of your request
(which in this case will be a translation from English to Italian).
Here is the XAML that composes our interface:
<Grid X:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</ Grid.RowDefinitions>
<TextBox Name="TextToTranslateTextbox" Text="Translate Me" />
<Button Name = "TranslateButton" Content = "Translate" Grid.Row = "1"
Click = "TranslateButton_Click" />
<TextBlock Name="TranslatedTextblock" Grid.Row="2" />
</ Grid>
Then in the code-behind of your PhoneApplicationPage, add class-level member as follows:
WebClient proxy = null;
The WebClient class
provides common methods for sending and receiving data from a resource
identified by an URI, so it's perfect for our purpose:
private WebClient proxy = null;
And now in the constructor of
your page you need to instantiate the proxy and prepare it to manage
the response of an OpenRead request,
proxy = new WebClient ();
proxy.OpenReadCompleted + = new OpenReadCompletedEventHandler (proxy_OpenReadCompleted);
In the event handler, you will
insert code to handle the response, but let's focus first on the
request, which will be linked to the click of TranslateButton:
...
private void TranslateButton_Click (object sender, RoutedEventArgs e)
{
try
{
if (String.IsNullOrEmpty (TextToTranslateTextbox.Text))
{
Uri request = buildGoogleTranslateRequest (TextToTranslateTextbox.Text);
proxy.OpenReadAsync (request);
}
}
catch (Exception ex)
{
// Do something with this exception
}
}
...
And buildGoogleTranslateRequest(string) is our private method that creates the URI for your request:
private Uri buildGoogleTranslateRequest(string textToTranslate)
{
return new Uri("https://www.googleapis.com/language/translate/v2?
key=YOUR_API_KEY_HERE&
q=" + textToTranslate + "
&source=en
&target=it
&prettyprint=true");
}
As a result of this request,
the application will give you an object serialized in JSON format—more
precisely, the format is as follows:
{
"Data": {
"Translations": [
{
"TranslatedText": "Text"
}
]
}
}
That tells you that the root object of the object graph has an internal object of type Date, which in turn contains an array of objects of type Translations, which in turn contains a property of type string called TranslatedText. Figure 1 shows the class diagram.
The implementation of GoogleTranslation is as follows:
GoogleTranslation.cs
[DataContract]
public class GoogleTranslation
{
[DataMember (Name = "data")]
public Data Data {get; set;}
}
Data.cs
[DataContract]
public class Data
{
[DataMember (Name = "translations")]
public List <Translation> Translations {get, set;}
}
Translation.cs
[DataContract]
public class Translation
{
[DataMember (Name = "translatedText")]
public string TranslatedText {get, set;}
}
...
The annotations on classes says you which type of serializer you will use —that is, DataContractJsonSerializer, which will be the focus of the implementation dell'eventHandler proxy_OpenReadCompleted.Il DataContractJsonSerializer System.ServiceModel.Web is contained in the assembly (so remember to add this reference to your project).
void proxy_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
var serializer = new DataContractJsonSerializer(typeof(GoogleTranslation));
GoogleTranslation translation = serializer.ReadObject(e.Result) as GoogleTranslation;
this.TranslatedTextblock.Text = translation.Data.Translations.FirstOrDefault() != null
? translation.Data.Translations.FirstOrDefault().TranslatedText
: "error in translation";
}
As you can see, the interaction
with a REST service is very simple, as is the use of JSON instead of
XML. The only difficulty you may encounter is the interpretation of the
object graph, to create a model for the deserialization of the response
(or the serialization of a request).
5. Usage
Open Visual Studio and start
deploying the application to the emulator. Write a sentence in the text
box and look for the translation. Of course, you need to stay connected
to the Internet to use this recipe.