
Network non-cross-platform

Hello! In this article, I would like to share my experience with novice developers who are learning to write mobile applications, but have not yet advanced very much in this field. To be precise - I would like to tell you how to write portable code and design applications that will work both on “native” .NET platforms (Windows Phone 7 and Windows desktop applications), and on ported versions of .NET for mobile platforms, such as Monotouch and Monodroid.
A little bit about Mono and Portable Class Library
In order to understand in detail how to write portable code correctly, you first need to understand how .NET works on iOS and Android. This topic is very large, therefore, as Vladimir Vladimirovich says, I will be brief.
Monotouch
Mono on iOS works as follows: no JIT compiler and no .NET on iOS itself. All code, absolutely all, including the entire .NET implementation, is compiled into native bytecode and “reaches” with the application distribution package.
The following “pros, cons and underwater rake” follow from here. Plus - performance (native code is by definition faster). Minus number 1: the size of the application distribution package is at least 6 MB. Minus number 2: unfortunately, only the Silverlight 4 profile is ported, and even that is not completely.
The main surprise: no generics and no reflection. And therefore - no games with collections, custom proxy classes for WCF, data binding a la WPF.
Monodroid
About .NET on Android, you need to say the following: at first glance, not everything is so sad: there is both JIT and generics. However ... Generics are inferior (parameter classes must inherit from Java.Lang.Object), and JIT is not exactly JIT. Here, too, you can highlight the topic for a separate article, if the Habrasociety is interested in this topic.
Portable Class Library and Windows Phone 7
The broadest possibilities for using C # are, of course, the mobile platform from Microsoft. Especially for her, a version of Silverlight was developed. However, the assemblies that were compiled for Windows Phone will not work on a desktop application. This is understandable, although very inconvenient: the target platforms are still different.
To adequately support code portability between Windows Phone and full .NET, the Portable Class Library (PCL) profile was implemented - a set of base classes that are present on all platforms that support the official version of .NET - Windows, Metro, Windows Phone, Silverlight, and Xbox.
Nuance
When developing for Mono *, you can directly refer to assemblies that were compiled for full .NET versions up to 3.5. And if your assembly uses only classes from the supported namespaces, everything will work fine. If you try to access an unrealized class, you just get a NotImplementedException; this is the white magic of the Monotouch compiler.
However, the project for Windows Phone 7 simply will not allow you to add a link to a similar collection (which is quite logical). “But what about the Portable Class Library? ..” - you ask. This is where black magic begins: when you try to use assemblies compiled for PCL or WP7 in Mono * projects, you get an error message: it is impossible to load an assembly that references libraries for WP7 or PCL.
I still do not understand why this is implemented in this way; To all questions about this technical support answers: "Coming soon." The only good news is that not so long ago a new version of MonoDevelop (development environment for Monotouch on Mac) was released, the description of which clearly indicated that partial support for PCL is implemented, but I could not understand exactly where.
Implementation
So, having the implementation of the libraries we need on all the platforms we are interested in, we cannot create one assembly for all platforms that uses the necessary classes. We will have to compile two assemblies - for Windows platforms and for Mono platforms.
But here again we are faced with a small problem. The most convenient class when implementing a client for a web service is WebClient. But it - for some mysterious reasons - was removed from the second edition of PCL, although it is implemented on Windows Phone 7 and in desktop applications. The developers argue this with the fact that WebClient is not supported in Metro-applications. Therefore, if you want to develop an application, including for Metro, you will have to use the lower-level classes WebHttpRequest and WebHttpResponse. For simplicity, I will show an example of implementing a proxy class for working with WebClient.
What we need:
- Visual Studio 2010 SP 1;
- Windows Phone SDK for Visual Studio 2010;
- Monodroid for Visual Studio 2010;
- MonoDevelop 3.0.2 on Mac;
- Newtonsoft.Json.
Getting to work.
1. Install the Windows Phone SDK and Monodroid. We create two projects: the first project is the Windows Phone Library, the second is the Android Class Library. If you want to develop a universal Windows library, create a Portable Class Library instead of the Windows Phone Class Library. But in this case, you will have to use the same less convenient HttpWebRequest and HttpWebResponse to work with the web service.
2. Next, we will conduct the main work with the Android Class Library. To ensure compatibility of this assembly with the Monotouch project, you need to make sure that there are no unnecessary links specific to Monodroid in this assembly. In the project, leave the following links:
- System
- System.Net;
- Newtonsoft.Json (a library for JSON deserialization).
3. Suppose that we have some kind of spherical REST service in a vacuum, which is located at http: // webservice: 47154 / rest / vendor and returns us a list of software manufacturers.

To use this service, it is enough to write the following code (create a class into which our web service response will be deserialized, and the proxy class itself, which the service will request).
//Контракт производителя ПО
public class Vendor
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
//Сам прокси-класс для работы с веб-сервисом
public class VendorsProxy
{
private string _host;
public VendorsProxy(string host)
{
_host = host;
}
public event VendorsEventHandler GetVendorsCompleted;
public void GetVendors()
{
var client = new WebClient();
client.DownloadStringCompleted += (s, e) =>
{
var vendors = JsonConvert.DeserializeObject>(e.Result);
if (GetVendorsCompleted != null) GetVendorsCompleted(new VendorsEventArgs(vendors));
};
client.DownloadStringAsync(new Uri(_host + @"rest/vendor"));
}
}
public delegate void VendorsEventHandler(VendorsEventArgs vendors);
public class VendorsEventArgs : EventArgs
{
public IEnumerable Vendors { get; private set; }
public VendorsEventArgs(IEnumerable vendors)
{
Vendors = vendors;
}
}
4. Now in the WP Library project it’s enough to add not the files themselves, but links to files from the Android Class Library project.

That, in fact, is all. Now, if you fully assemble the solution, the output will be two assemblies that will work equally well both in Windows Phone, and on devices with iOS and Android. You can use your web service on any platform as follows.
var proxy = new VendorsProxy("http://mywebservice:8080/");
proxy.GetVendorsCompleted += (vendors) =>
{
BindVedorsToVoewModel(vendors.Vendors);
};
proxy.GetVendors();
Doubt
Of course, one can argue about the need for such "dances with a tambourine" to achieve such universality: for sure, each platform will have its own specifics and its own optimal working methods. However, if you are a confident .NET programmer and you need to quickly create a simple mobile application that works with a web service, this solution can be useful.
If the Habrasociety is interested in this topic, then in the next article I will talk about methods for protecting connections in cross-platform applications.
Posted by Sergey Shulik, Senior Programmer, Positive Technologies.