5

I recently added a custom UriMapper for saving files into my applications isolated storage when opening them from IE. The code for this looks like this:

class AssociationUriMapper : UriMapperBase
{
    public override Uri MapUri(Uri uri)
    {
        var tempUri = uri.ToString();

        if (tempUri.Contains("/FileTypeAssociation"))
        {                
            int fileIdIndex = tempUri.IndexOf("fileToken=") + 10;
            string fileId = tempUri.Substring(fileIdIndex);

            SaveFileToIsolatedStorage(fileId);

            return new Uri("/MainPage.xaml", UriKind.Relative);                
        }

        return uri;
    }
}

In InitializePhoneApplication() I do a

RootFrame.UriMapper = new AssociationUriMapper();

And of course I've added the Extensions tag to WMAppManifest.xml

All this works fine... but I noticed a strange behaviour. I get two copies of the files each time I open them from IE. When I put a breakpoint inside my overridden MapUri it gets hit twice every time the application autolaunches from IE.

When I started to investigate this further I noticed that this happens whenever I call NavigateService.Navigate(). But not when I call NavigateService.GoBack.

Do anyone know why this is happening? Why are MapUri() called twice when Navigate() is called? Is it something that happens when a new instance of a page is created? (I've noticed that when we call Navigate() a new instance of the called page is created, but when we call GoBack() we retrieve the already created instance of the page we navigated from).

Edit:
I've now done a little test application from scratch. The result is the same. If I have a class that inherits from UriMapperBase and overrides the MapUri method, MapUri is called twice whenever I navigate to the application or call NavigateService.Navigate() in the application.

The obvious workaround for my problem is of course to have a separate page that the application navigates to and that page call SaveFileToIsolatedStorage(). But that still doesn't answer the question why the behaviour is as it is.

mattsson
  • 1,132
  • 12
  • 18
  • I have the same problem and it's really annoying for the behavior of my app – Paul Martinez Mar 28 '14 at 10:22
  • Yes. It's very strange. It definitely has something to do with how things are called when creating a new object of a page. Some round trip of some sort that calls MapUri() twice. Can you in anyway move your logic away from the MapUri() method? If you do your logic in the OnNavigatedTo() in a separate view without calling the Initialize() in the constructor and then navigate back to the page you want to show the logic will only be run once and the user will not see the page you navigate to since you don't initialize it. That´s how I solved my problem. – mattsson Mar 28 '14 at 14:00
  • Thank you for the tip it could be useful – Paul Martinez Mar 31 '14 at 08:42

3 Answers3

3

Try hooking up the UriMapper through the XAML of the MainPage using a ViewModel instead of through code.

Muster Station
  • 504
  • 2
  • 9
0

Some cheat in my code to keep only one event.

    private static string lockUri = "";

    public override Uri MapUri(Uri uri)
    {
        lock (lockUri)
        {
            if (lockUri != uri.ToString())
            {
                lockUri = uri.ToString();
                return null;
            }
        }

        // Your code to route here
    }
t4nhpt
  • 5,264
  • 4
  • 34
  • 43
0

that is what I do:

public class AppUriMapper : UriMapperBase
{
    public static bool IsNavigating = false;

    public override Uri MapUri(Uri uri)
    {
        var endUri = uri;

        if (IsNavigating)
        {
            IsNavigating = false;

            //blabla......
        }

        System.Diagnostics.Debug.WriteLine("goto: [origin] {0} [dest] {1}", uri, endUri);

        return endUri;
    }
}

in App.cs:

RootFrame.Navigating += (s, e) =>
        {
            AppUriMapper.IsNavigating = true;
            System.Diagnostics.Debug.WriteLine("goto: [mode] {0}, [uri] {1}", e.NavigationMode, e.Uri);
        };

look ok.

Cologler
  • 724
  • 6
  • 18