UriMapper hacks – Intro, basic Uri rewriting

UriMapper is a little known (at least by me) property that can be used for various hacks. So what is it exactly, where it is and how do you use it? Welcome aboard.

It is located in the Frame class and is of type UriMapperBase which is an abstract class. By default this property is set to null and therefore doesn’t affect your app at all. The official documentation for the class states:

Represents the base class for classes that convert a requested uniform resource
identifier (URI) into a new URI based on mapping rules.

So, whenever you initiate a navigation via NavigationService methods, an instance of this class is supposed to do some transformation of the incoming Uri and adjust it if necessary. If set to something other than null, of course.

So, if we want to change how the default navigation works, we need to create our own UriMapper class which will handle the Uri transformation. So let’s implement our own mapper.

Let’s create a new class called IdentityUriMapper which inherits UriMapperBase. Since the base class is abstract, we need to implement some abstract functions – in this case we only have one: Uri MapUri(Uri uri). The function receives a Uri and it is supposed to return another Uri out. Here is the implementation of the IdentityUriMapper:

internal class IdentityUriMapper : UriMapperBase
{
	public override Uri MapUri(Uri uri)
	{
		return uri;
	}
}

Don’t forget to initialize our RootFrame with it!

RootFrame = new PhoneApplicationFrame
{
	UriMapper = new IdentityUriMapper()
};

If you copy the code above to your application and run it, the application would run as if we haven’t made any changes at all. But if you would set a breakpoint in the MapUri function, it would break whenever you navigate to some page or hit the back button. Oh, and it would break twice for each forward navigation, and it wouldn’t break if you leave the application or return to it.

Since that was rather trivial example, it’s time to exploit the mapper to do some basic Uri rewriting. Why would you do that, you might ask. Well, whenever you want to navigate to some page, your code might look something like this:

NavigationService.Navigate(new Uri("/SettingsPage.xaml", UriKind.Relative));

This is pretty verbose and some pieces are redundant. What you might want to write is:

NavigationService.Navigate(new Uri("Settings"));

Creating our own mapper will allow us to do that. The code will be simple: if the input uri already ends with .xaml, ignore it. Otherwise, reformat it. Here is the full code:

public class BasicBasicUriRewriter : UriMapperBase
{
	public override Uri MapUri(Uri uri)
	{
		if (uri.OriginalString.EndsWith(".xaml"))
			return uri;

		return new Uri("/" + uri.OriginalString + "Page.xaml", UriKind.Relative);
	}
}

Unfortunately, turns out you must specify UriKind.Relative when creating the uri. Otherwise, the constructor will fail.

If you are using MVVM, you might put all your views inside a Views folder. You can easily alter the rewriter code above to prepend the full path to the newly constructed uri. This way you can move your views around, but the navigation will work regardless.

Although this remnant from Silverlight era is not actually needed in Windows Phone due to the fact that no one ever sees URL-s in their apps, the concept of rewriting the URL is still useful. This is very light intro and in my next posts I will show how to use this powerful technique for some advanced rewritings. Happy coding.

Last updated by at .