Windows Phone app calls MapUri() twice when I call

2019-04-30 04:32发布

问题:

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.

回答1:

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



回答2:

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
    }


回答3:

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.