Using UriMapper

I bumped into an interesting issue with UriMapper on Windows Phone 8.

I followed the instructions here to redirect user to AccountPage.xaml page when they haven’t entered their credentials yet. After the user has logged in I tried to navigate back to MainPage.xaml, but I couldn’t and the app wasn’t throwing any exceptions.

Eventually I figured out that NavigationService.CurrentSource was saying the app was on MainPage.xaml even though I was on Account.xaml.

Turns out that when mapping with UriMapper that does not affect NavigationService.CurrentSource property, the property remains set to the value of original Uri. And at app startup that was the Uri as configured in WMAppManifest.xml:

    
      
    

My UriMapper implementation was like this:

    public class PageUriMapper : UriMapperBase
    {
        private readonly MainViewModel _viewModel;

        public PageUriMapper(MainViewModel viewModel)
        {
            _viewModel = viewModel;
        }

        public override Uri MapUri(Uri uri)
        {
            if (!_viewModel.Settings.IsValidUsername)
            {
                return new Uri("/AccountPage.xaml", UriKind.Relative);
            }
 
            return uri;
        }
    }

So I decided to set the startup page in WMAppManifest.xml to a page that does not exist in my project:

    
      
    

I modified my UriMapper to be like:

    public class PageUriMapper : UriMapperBase
    {
        private readonly MainViewModel _viewModel;

        public PageUriMapper(MainViewModel viewModel)
        {
            _viewModel = viewModel;
        }

        public override Uri MapUri(Uri uri)
        {
            if (uri.ToString().Contains("StartPage"))
            {
                if (!_viewModel.Settings.IsValidUsername)
                {
                    return new Uri("/AccountPage.xaml", UriKind.Relative);
                }
                else
                {
                    return new Uri("/MainPage.xaml", UriKind.Relative);         
                }
            }
 
            return uri;
        }
    }

And voila! My navigation began to work since “StartPage.xaml” != “MainPage.xaml” :)