Thursday, February 19, 2009

Running WPF in a Browser

Aaarrrggghhhh!!!!! Microsoft Security Exceptions!

I have been trying to get my first example of an XBAP file running in a browser. I am using the book Essential Windows Presentation Foundation, by Chris Anderson. I did not have any problems with Chapter 1 and was able to download the source code for the more complicated examples at the end of the chapter.

Chapter 2 does not have any source code available. I was trying to run a very simple "Hello World" application. I was still using the command line to run my examples, just to get a feel for the syntax of the project and application files. I ran the application as an exe without a problem. Next, I added the property in the project file to allow the app to run in the browser.

<PropertyGroup>
<HostInBrowser>true</HostInBrowser>
</PropertyGroup>

When I ran it, I received an error about signing the manifest.

Error 3 The ClickOnce manifest for XAML Browser Applications must always be signed. You must specify properties: SignManifests (value set to True), and either ManifestKeyFile (with the name of your key file) or ManifestCertificateThumbprint (hexadecimal thumbprint value in SHA-1 format, of key file). Alternatively, you may use your IDE's Publish Wizard or Signing options.


I referred back to the book and saw a footnote about singing manifests using Visual Studio. I opened Visual Studio and created a new WPF Project. A lot of files were created for me. I signed the manifest from the Properties -> Signing tab. I created a temporary certificate. I ran the simple application as an exe and it worked. I edited the csproj in a text editor and added the code for running in a browser. I tried to run the app from VS, but could not, since it is meant to be run in the browser. I found the XBAP file in the file system and double-clicked it. The browser opened and I received this error.

System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

Looking further in the error list, I noticed that the assembly did have UIPermission, but only for save top level windows. I then remembered that the example from the book used Page as the base class, but that the default application in VS used Window. I edited the project so that it used Page instead of Window. I still had the same error.

When I had developed this from a different computer, I received a different error about the assembly not allowing partially trusted callers to use it. I had resolved this on the other computer, so I thought it might be a problem on this one. There is a very detailed explanation of the problem on the web. The trick is to add the AllowPartiallyTrustedCallers attribute to the code-behind file, at the assembly level.

using System.Security;
[assembly: AllowPartiallyTrustedCallers]

I still had the error. I had seen some posts on the web about similar errors that referred to publishing the application, so I published it, using the Build menu. The URL that was generated had an extra " at the end, so it failed. After removing that, I was given a directory listing. I double-clicked the XBAP file and it worked.

Since I had made so many changes before the application worked, I backtracked to see which one(s) had done the trick. The only one that I did not need was for the PartiallyTrustedCallers. Apparently, the computer I am using now has different access rights than the one I was using earlier, so I will keep the assembly attribute in the final solution.

Looking back at the first error I received, I see that it suggests using the IDE's signing or publishing wizards to sign the manifest; apparently, both signing and publishing are needed.

PS. There was another error that I saw referenced on the web about the application cache. At some point I also tried clearing it. The process was to close the browser, open the VS commmand prompt and execute the command mage -cc. The command took a minute to complete. I do not think this had anything to do with getting my example to run.

PPS. I have reconfigured the application for the original computer: I changed the app from a base class of Window to Page and published the application. I did not need to add the partially trusted attribute. To be more specific, I ran it with the attribute, then I removed the attribute, rebuilt, republished and it still ran.
 

No comments:

Post a Comment

Followers