Exactly as the title says, remember to encode the url you want to open in the external browser via the WebBrowserTask, always.

This is probably the first of a series of posts I’m going to write about some problems I found while developing FeedTso, a feed news reader application for WP7, of course with the solution.

But let’s go back to the problem.

How to open a url in the WP7 web browser from your application

Well, this is easy:

WebBrowserTask task = new WebBrowserTask();
task.URL = "http://feedtso.com/";
task.Show();

Just create the task, set the URL (remember, it is a string, not a Uri) and call the Show method.

Adding parameters to the mix

But with more complex urls, with parameters or when the parameter is another url, things go wrong.

In my news reader I let users open the post in the external browser also in text-only mode, using a third party service from Instapaper, called mobilizer.

To make it work you have to call the url http://www.instapaper.com/m and add a parameter named u with the url of the page you want to be “mobilized”.

But in order to add it as parameter, the url has to be encoded to make it legal as uri: so if you want to see the text-only version of the features of FeedTso you have to call the following url (which is urlencoded):

http://www.instapaper.com/m?u=http%3A%2F%2Ffeedtso.com%2Ffeatures.html

This works fine if typed manually into the address bar of a browser, but if I send this url to the web browser task, I see the decoded url, which is invalid and thus generates a bad response from the server.

I looked at the URL property on MSDN and it says:

Remark:
URLs that contain special characters must be escaped before being assigned to the URL property. Use the Uri.EscapeDataString method to escape the URL string.

I thought it was only applying to the normal url encoding you do if your parameters have special characters. But apparently it means that everything has to be UrlEncoded, also after having already encoded the parameter.

Probably the web browser task always decode the url before sending it to the browser, and in my case it was decoding also the encoding of the url parameters and was making the navigation fail.

How to navigate to a Uri with parameters?

The gotcha is that you have to encode it again before passing the url to the WebBrowserTask.

string serviceUrl = "http://www.instapaper.com/m?u=";
string destinationUrl = "http://feedtso.com/features.html";
string escapedUrl = serviceUrl + Uri.EscapeDataString(destinationUrl);
WebBrowserTask task = new WebBrowserTask();
task.URL = Uri.EscapeDataString(escapedUrl);
task.Show();

Encoding it the second time would generate an invalid url:

http%3A%2F%2Fwww.instapaper.com%2Fm%3Fu%3Dhttp%253A%252F%252Ffeedtso.com%252Ffeatures.html

But apparently that’s the only way to have the WebBrowserTask behave correctly.

Wrapping up

This also seems like one of the gotcha WP7 developers might need to live with, as I don’t think Microsoft will ever be able to fix this as by doing so it will break all the applications that already workaround that strange behavior.

This also got confirmed by Jonathan Tanner on the on the WP7 Development forum:

Unfortunately this seems to be be a “gotcha” that WP7 developers will have to live with since changing this behavior in a future update would break existing apps that take into account the remarks for that property.

So, we have to learn to live with it.