Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebClient encoding issue in MonoTouch when building for release

I have been having issues with WebClient behaving differently in release builds on real devices than in debug mode the iOS simulator.

Apparently the response from the server gets interpreted differently, and breaks in release builds: Screenshot from the DEBUG build running in the iOS Simulator Screenshot from the RELEASE build running on an iPhone 4S

This question seems to have an answer for a similar issue, but I don't want to hardcode the encoding in the app, even though it might not change in its lifetime, it seems wrong to do so as the information is already contained in the HTTP response.

I have already opened an issue with Xamarin to investigate this further.

like image 207
Timm Avatar asked Nov 27 '25 10:11

Timm


2 Answers

There are two factors in play here. First:

it seems wrong to do so as the information is already contained in the HTTP response

Yes, it does look wrong but Microsoft .NET's WebClient.Encoding is, by default, identical to System.Text.Encoding.Default.

MSDN quote:

The default value of this property is the encoding returned by Default.

As such Mono (and MonoTouch) implementation of WebClient behave identically. This is often overlooked (works mot of the time) but it's a source of hard to find (not MonoTouch but .NET specific) bugs since there's no warranty about what the Default value can be.

MSDN quote:

Different computers can use different encodings as the default, and the default encoding can even change on a single computer.

The second factor is the iOS simulator is that: a simulator not an emulator. This has many benefits (e.g. it's much faster than Android emulators) but it also has it's drawbacks (few IMO but it only makes them harder to spot).

What this means is that the simulator does not try (much) to hide the underlying operating system (i.e. OSX) when using general purpose API, like getting the default code page. Since it returns a different value, System.Text.Encoding.Default will be initialized with a different code page, leading to a different implementation being used.

As such setting your own encoding to WebClient.Encoding is the correct (and safe) way to solve your issue (for any .NET application).

like image 146
poupou Avatar answered Nov 28 '25 23:11

poupou


I heard back from the Xamarin support team and they also suggested setting the WebClient encoding explicitly.

On my device the WebClient.Encoding was set to System.Text.Encoding.ASCII instead of UTF8, which is used in the iOS Simulator.

Still not a generic solution, but at least you can use the high-level DownloadString:

using (var client = new WebClient())
{
    client.Encoding = System.Text.Encoding.UTF8;
    var response = client.DownloadString("http://dl.dropbox.com/u/58977881/umlautTest.txt");
}
like image 41
Timm Avatar answered Nov 28 '25 22:11

Timm