SL out of browser and loading xaml config from server

Topics: Silverlight Integration Pack
Apr 27, 2012 at 3:03 PM

Hello,

I have a SL application that uses prism and the EntLib SL integration pack. Similar to the Stock Trader V2 reference implementation on application startup it asynchronously loads the EntLib xaml config from the server and then on successful configuration it creates and runs the prism bootstrapper that sets the root visual.

Now I have configured the SL application to run out of browser. When out of browser the SL application is not happy at all that no root visual is set on application startup. The asynchronous loading of the EntLib xaml config never completes (if the request was successfully sent at all) and therefore the prism bootstrapper is never created and run and hence no root visual is set. Anybody know why this may be?

For now I have included the Configuration.xaml in the xap file for out of browser use, while in browser I still retrieve the xaml from the server:

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            if (IsRunningOutOfBrowser && HasElevatedPermissions)
            {
                // Create and run the bootstrapper. Prism uses a bootstrapper to load and configure all modules 
                // and start the application. 
                var bootstrapper = EnterpriseLibraryContainer.Current.GetInstance<Bootstrapper>();
                bootstrapper.Run();
            }
            else
            {
                // When the application starts, we have to download the XAML configuration first. After that, we can continue to start the application. 
                EnterpriseLibraryContainer.EnterpriseLibraryConfigurationCompleted += this.OnEnterpriseLibraryConfigurationCompleted;
                EnterpriseLibraryContainer.ConfigureAsync(new Uri("../Configuration.xaml?version=" + DateTime.Now.Ticks, UriKind.Relative));
            }
        }

Now my application will start up ok. Any subsequent service calls to the server work ok, so I have no idea why the EntLib xaml config would not load. Perhaps its all to do with having to set a root visual immediately on application startup when out of browser, while in browser you can defer this till the EntLib xaml config has loaded.

Remco

Editor
Apr 30, 2012 at 4:31 AM

Since it is working for the in-browser application my guess would be that there is some security issue that is preventing the configuration XAML file from being loaded.  I would try adding a clientaccesspolicy.xml file to the target web site to see if that helps.  Even with a clientaccesspolicy.xml file you can still hit other issues such as cross domain calls between security zones (see http://blogs.msdn.com/b/fiddler/archive/2010/11/22/fiddler-and-silverlight-cross-zone-cross-domain-requests.aspx).

To troubleshoot Fiddler and ProcMon are very useful.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Apr 30, 2012 at 9:22 AM
Edited Apr 30, 2012 at 9:23 AM

Hi Randy,

Thanks for your help. Fiddler shows no requests being submitted at all and the EnterpriseLibraryConfigurationCompleted event handler is not raised at all and my application window remains blank. However, when I set a temporary root visual on application startup

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            this.RootVisual = new TextBlock { Text = "Loading Enterprise Library configuration." };
            // When the application starts, we have to download the XAML configuration first. After that, we can continue to start the application. 
            EnterpriseLibraryContainer.EnterpriseLibraryConfigurationCompleted += this.OnEnterpriseLibraryConfigurationCompleted;
            EnterpriseLibraryContainer.ConfigureAsync(new Uri("../Configuration.xaml?version=" + DateTime.Now.Ticks, UriKind.Relative));
        }

Fiddler shows the request for the xaml config file being sent and a response being received successfully. The EnterpriseLibraryConfigurationCompleted event is raised. However, my OOB application continues to show the temporary root visual. My prism bootstrapper that is run on EnterpriseLibraryConfigurationCompleted is unable to replace the root visual. No exception is thrown either. It looks like in an OOB application the root visual can only be set once and must be set on application startup and no later.

I suppose I could continue to include the xaml config in the xap file, run my prism bootstrapper on application startup setting my root visual and then load the xaml config from the server asynchronously and update the EntLib unity container registrations if the config on the server is different from the one in the xap file. Would that be possible?

 

Editor
Apr 30, 2012 at 5:34 PM

Yes, "you can set the value of the RootVisual property only one time from code, although you get its value any number of times".

The blog post Silverlight: web service calls fail when OOB says that when running out-of-browser you can't call a web service before setting the RootVisual.  Although, I couldn't find any formal confirmation for this exact scenario it agrees with what you are seeing.

In general, your idea of setting the RootVisual and then updating the container sounds good.  I have concerns in practice since the BootStrapper injects into the modules Enterprise Library objects (which are then assigned to readonly variables).  So even if the container was updated with new configuration it looks like it would not be reflected in some objects.  Of course, this is based on the Stock Trader Application so a different application might be easier to work with.  

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

May 1, 2012 at 1:26 PM
Edited May 1, 2012 at 1:26 PM

Hi Randy,

Thanks for your help and the links to the articles.

What I ended up doing is setting a ContentControl as the root visual on application startup, allowing me to asynchronously load the xaml config, and then when my prism bootstrapper runs I set the shell view as the ContentControl's content. like so:

        private void OnApplicationStartup(object sender, StartupEventArgs e)
        {
            if (IsRunningOutOfBrowser && HasElevatedPermissions)
            {
                this.RootVisual = new ContentControl { HorizontalContentAlignment = HorizontalAlignment.Stretch, VerticalContentAlignment = VerticalAlignment.Stretch };
            }

            // When the application starts, we have to download the XAML configuration first. After that, we can continue to start the application. 
            EnterpriseLibraryContainer.EnterpriseLibraryConfigurationCompleted += this.OnEnterpriseLibraryConfigurationCompleted;
            EnterpriseLibraryContainer.ConfigureAsync(new Uri("../Configuration.xaml?version=" + DateTime.Now.Ticks, UriKind.Relative));
        }

and

        protected override void InitializeShell()
        {
            base.InitializeShell();

            if (Application.Current.IsRunningOutOfBrowser && Application.Current.HasElevatedPermissions)
            {
                var rootVisual = (ContentControl)Application.Current.RootVisual;
                rootVisual.Content = this.Shell;
            }
            else
            {
                Application.Current.RootVisual = (UIElement)this.Shell;
            }
        }

kind regards

Remco