24 November, 2010

WP7: How to consume JSON data on a Windows Phone 7 application

Having witnessed the small footprint of JSON compared to SOAP, I’ve begun taking a real liking in using JSON formatted WCF-services. On top of that, I in particular like the fact that you are actually able to “map” the fields coming from the JSON formatted string into a local object representation using the DataContract attribute in a way I never thought of. Well – here goes.


Server side: This is the JSON formatted data what is received from the WCF service:


[{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"}]

This is just a simple name-value array of strings. See this post for info on how to enable this JSON formatting: http://blog.clauskonrad.net/2010/11/how-to-expose-json-endpoint-from-wcf.html.


And see this post on how to call out to the WCF service from the WP7 application: http://blog.clauskonrad.net/2010/11/wp7-how-to-make-httprequests-from.html


Client side: Now – to convert this string into a local object representation, you can use the DataContract attributes in a real clever way. Notice how the “objects” coming out of the JSON string supposedly suggest this structure:

public class MyClass
{
public int BirthYear { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}


But – what if I want a different set of properties and a completely different class name?



This is where the DataContract kicks in to help out! Using this class, you can actually map this JSON string into your own object construction at will. You start by declaring your own local representation (MyPersonClass) and decorating this with Name=’JSON-field name’. In this way – the DataContractJsonSerializer will handle the mapping.

[DataContract]
public class MyPersonClass
{
[DataMember(Name="BirthYear")] //mapping: BirthYear -> BornYear
public int BornYear { get; set; }

[DataMember(Name = "FirstName")] //mapping: FirstName -> Name
public string Name { get; set; }

[DataMember(Name = "LastName")] //mapping: LastName -> SurName
public string SurName { get; set; }
}


To actually perform the deserialization, you simply go:

//load into memory stream
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
//parse into jsonser
var ser = new DataContractJsonSerializer(typeof(MyPersonClass[]));
MyPersonClass[] obj = (MyPersonClass[])ser.ReadObject(ms);
}


This leaves you with an array of ‘MyPersonClass’ objects coming out of the JSON string! Pretty sweet functionality!



Technorati Tags: ,,

23 November, 2010

How to expose a JSON endpoint from a WCF-service

Having seen the small footprint set by JSON – I’ve begun using it extensively for mobile device (WP7) communication. In particular the phone scenario makes it desirable to have an as small as possible data load to transfer between server and device. When using the JSON formatting, you can really minimize the load as documented here. Below is what is returned in JSON-format (compare that to the verbose OData or SOAP formatting!):

[{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"}]

How to do ?
To expose a WCF-implemented service with JSON support, you need to setup these artifacts:

Service Contract:
First define the contract for the service to expose.

namespace WebService1
{
[ServiceContract(Namespace="http://someethingelse.com")]
public interface IEmployeeService
{
[OperationContract]
[WebInvoke(BodyStyle=WebMessageBodyStyle.Bare, ResponseFormat=WebMessageFormat.Json)]
Employee[] GetAll_POST();

[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
Employee[] GetAll_GET();
}

[DataContract(Namespace="http://somethingunique.com")]
public class Employee
{
[DataMember]
public int BirthYear { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
}
}

Note the WebInvoke and WebGet attributes on the service definition. The WebInvoke attribute specifies that the method will obey POST-requests, where as the WebGet attribute will make the method obey GET-requests.

The two attributes takes parameters that allows for specifying in which format the data should be formatted. When the ResponseFormat=WebMessageFormat.Json is set, the data returned by the method is formatted as a clean and simple JSON notation.


Web.config
Of-course you also need to setup configuration in the web.config. Here you should pay special attention to the binding and the behaviorConfiguration attributes.
Important: In particular the endpointBehavior should have <webHttp> set as content to gain the clean JSON formatting (see below).

  <system.serviceModel>
<
services>
<
service name="WebService1.EmployeeService">
<
endpoint name="jsonEP"
address=""
binding="webHttpBinding"
behaviorConfiguration="json"
contract="WebService1.IEmployeeService"/>
</
service>
</
services>
<
behaviors>
<
endpointBehaviors>
<
behavior name="json">
<
webHttp/>
</
behavior>
</
endpointBehaviors>
</
behaviors>
</
system.serviceModel>

Client:
When calling the above service, you will receive a nicely formatted JSON string like this:


[{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"}]


That’s how easy it is setting up when using WCF.


Technorati Tags: ,

22 November, 2010

WP7: How to detect if I have a valid network connection?

Building a remote logviewer, I was in need of calling out to a webservice to retrieve logging lines for display on the mobile device (Windows Phone 7 application). Now – it turned out that I sometimes lost network connection on the phone which ultimately led to exceptions I had never anticipated in my application logic. Due to this reason – I found the below procedure to work that advices my application logic that there is no network coverage, which allows for taking the proper measures in the code.

First – set up an eventhandler in app.xaml.cs (your main application file) that listens to changes in network connection. A change in network connection will provide you with a new network address, hence this event will be used to provide you with info on “network state”.

// Constructor
public App()
{
// Global handler for uncaught exceptions.
// Note that exceptions thrown by ApplicationBarItem.Click will not get caught here.
UnhandledException += Application_UnhandledException;

// Standard Silverlight initialization
InitializeComponent();

// Phone-specific initialization
InitializePhoneApplication();

PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;

NetworkChange.NetworkAddressChanged += new NetworkAddressChangedEventHandler(NetworkChange_NetworkAddressChanged);
}


After this event hooking – you can handle the different networkstates. Here retrieve the currently active network  interface type. In particular – the NetworkInterfaceType.None is important, as this indicates that you have lost network connection completely and it therefore makes no sense attempting to make a call (e.g. http-request) from your application.

        void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
{
var type = Microsoft.Phone.Net.NetworkInformation.NetworkInterface.NetworkInterfaceType;

switch (type)
{
case Microsoft.Phone.Net.NetworkInformation.NetworkInterfaceType.None:
break;
case Microsoft.Phone.Net.NetworkInformation.NetworkInterfaceType.AsymmetricDsl:
break;
case Microsoft.Phone.Net.NetworkInformation.NetworkInterfaceType.Atm:
break;
case Microsoft.Phone.Net.NetworkInformation.NetworkInterfaceType.BasicIsdn:
break;
case Microsoft.Phone.Net.NetworkInformation.NetworkInterfaceType.Ethernet:
break;
//rest omitted...


Technorati Tags:

20 November, 2010

WP7: How to make (async) HttpRequests from Windows Phone 7 application

Had a little challenge today about calling out to a JSON endpoint from a phone application. It turned out to be quite easy – but it took some time to have it setup correctly! Hope this helps others facing the same problems.

image

First – calls to anything “outside” the phone should be done asynchronously to make the UI responsive while the call is taking place:

var req = (HttpWebRequest)WebRequest.Create(@http://www.abzcompany.net/infoservice.svc/json/GetAllData);
req.Method = "POST";
req.ContentType = "application/json; charset=utf-8";

//call async
req.BeginGetResponse(new AsyncCallback(jsonGetRequestStreamCallback), req);

Next – await the call back in a new method:
void jsonGetRequestStreamCallback(IAsyncResult asynchronousResult)
{
WebResponse response = ((HttpWebRequest)asynchronousResult.AsyncState).EndGetResponse(asynchronousResult);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string responseString = reader.ReadToEnd();
reader.Close();

//deserialize using datacontract serializer (not shown)

}
}


That’s how easy it is!



Technorati Tags:

19 November, 2010

WP7: How to disable the lockscreen

If you want to prevent the lockscreen from appearing, set this in App.xaml.cs:

public partial class App : Application
{

// Easy access to the root frame
public PhoneApplicationFrame RootFrame { get; private set; }

// Constructor
public App()
{
// Global handler for uncaught exceptions.
// Note that exceptions thrown by ApplicationBarItem.Click will not get caught here.
UnhandledException += Application_UnhandledException;

// Standard Silverlight initialization
InitializeComponent();

// Phone-specific initialization
InitializePhoneApplication();


PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled;
}

Update:
It’s actually not that difficult – it goes like this



  1. Select the app.xaml file
  2. RightClick the file/or press F7
  3. Enter this line in the contructor:
    image


Technorati Tags:

WP7: Application Icons and how to create

Stumbled upon a good video on how to create custom application Icons and backgrounds.
Video here: http://www.nfynite.com/2010/10/23/wp7-video-tutorial-changing-the-iconssplash-screen/

Data:
You need 2 icons. These should be this size:

Icon Size Extension
Small 62 x 62 pixels .png
Large 173 x 173 pixels .png

SplashScreen:
The splash screen image should of-course fill the screen, hence this will apply: 480 x 800 (.png)

Technorati Tags:

InRiver: Not loading your extensions?

(You really need to in the loop to appreciate the issue this post addresses). Man, I've been fighting this problem for hours before I ...