XBap + Web Service Problem
Hello,
I am having a real strong difficulty simply having an XBap display "Hello World" from a web service. I have attempted this several times and have been involved in several threads related to this without resolution.
To pinpoint the problem, I have reproduced it in it's simplest form available here:
http://www.mediamax.com/alanzow/Hosted/WPFTest.zip
In this solution, there exists a
- Class Library
- Web Service Project
- ASP.NET site
- Windows Forms Application
- WPF XBap project
The webservice simply creates an instance of an object within the class library. The object has a method that does nothing more than return "Hello World". The web service has a webmethod that returns this value.
I then use the three client projects (the ASP.NET application, the windows forms application, and the WPF XBap) to connect to the webservice and display "Hello World". The ASP.NET application and the Windows Forms Application works perfectly. However, I receive the mysterious "XamlParseException" from my XBap.
Can someone please help me? I have grown incredibly frustrated with this problem. I haven't seen any blog posts related to this and I can't believe I'm the only one who has experienced this. I hate to be pushy, but if I do not get this resolved this week, I will be unable to use WPF on my project. Can someone help?
Thanks,
Alan
Answers
Hello, Alan.
This is a security issue. By default, XBAPs run in partial trust environment. There’re several restrictions. You can demand more permission, but only a user who trusts you enough can run it.
If you put your code in a try catch block, you can find what permissions it need.
try
{
Service1Proxy.Service1 service = new WPFXbapClient.Service1Proxy.Service1();
lblHelloWorld.Content = service.HelloWorld();
}
catch (Exception ex)
{
lblHelloWorld.Content = ex.Message;
}
Too get the permissions, right click the XBAP project in the Solution Explorer, choose Properties. Under Security Tab, you can find a list of “Permissions required by the application”. Change the settings of those you need from the default “Zone Default” to “Include”. I found that after set the “Environment Permission” and the “Web Permission”, your application will run properly.
Also you can simply select “This is a full trust application”. But be aware that it may introduce some security issues to your customers’ machine.
Sorry for the inconvenience, but please understand that security is a major concern in all software development. Hope this can solve your problem.
All Replies
- bump...
Hello, Alan.
This is a security issue. By default, XBAPs run in partial trust environment. There’re several restrictions. You can demand more permission, but only a user who trusts you enough can run it.
If you put your code in a try catch block, you can find what permissions it need.
try
{
Service1Proxy.Service1 service = new WPFXbapClient.Service1Proxy.Service1();
lblHelloWorld.Content = service.HelloWorld();
}
catch (Exception ex)
{
lblHelloWorld.Content = ex.Message;
}
Too get the permissions, right click the XBAP project in the Solution Explorer, choose Properties. Under Security Tab, you can find a list of “Permissions required by the application”. Change the settings of those you need from the default “Zone Default” to “Include”. I found that after set the “Environment Permission” and the “Web Permission”, your application will run properly.
Also you can simply select “This is a full trust application”. But be aware that it may introduce some security issues to your customers’ machine.
Sorry for the inconvenience, but please understand that security is a major concern in all software development. Hope this can solve your problem.
Hi Yi-Lun,
Thank you for your assistance. I understand that security is a major concern and I appreciate Microsoft's efforts around this topic. I wasn't aware of what I needed to do in Visual Studio to get it to run, I just assumed it should have run by default. I'm guessing this will be remedied by Visual Studio "Orcas".
Thanks,
Hi Yi-Lun,
I attempted changing the security of the XBAP project to "Include" for the Environment Permission and the Web Permission and I still received the same error. I then changed to "Full Trust" and I still receive the same error. Is there anything else it could be?
Hello Alan,
Hopefully you are still with us... I looked at your test project and tried to make it work. There were a couple of hurdles to overcome. [Note that web development is not my forte, so it wasn't hard to put myself in your shoes. ;-) I experienced some of your frustration.]
First, Yi-Lun's suggestion is apparently not applicable to your situation, because you are trying to build a standard Internet-zone XBAP. It has to run with the permissoion set allowed for that zone.
Note that my experience is from Windows Vista (with IIS 7).
[1] "Application Download Error" when trying to run the XBAP. The log file showed:
+ Downloading http://localhost/WPFXbapClient_1_0_0_0/WPFXbapClient.exe.config did not succeed.
+ The remote server returned an error: (404) Not Found.
I checked the folder under wwwroot, and the file was there, so publishing from Visual Studio didn't seem to be the problem. I tried to navigate the browser directly to the file and got the real explanation:HTTP Error 404.7 - Not Found
Description: The request filtering module is configured to deny the file extension
It took some head-scratching and searching to figure out how to enable .config files to be deployed. I'm not sure whether this is the correct solution security-wise, but here's what I ended up doing:1. In the Web.config file, added:
<system.webServer>
<security>
<requestFiltering>
<fileExtensions allowUnlisted="true">
<remove fileExtension=".config" />
<add fileExtension=".config" allowed="true" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>2. To make IIS accept the setting override, I had to change a line in System32\inetsrv\config\applicationHost.config:
<section name="requestFiltering" overrideModeDefault="Allow" />
After these tweaks I got the XBAP to fail with the following error.
[2] System.Windows.Markup.XamlParseException: Cannot create instance of 'Page1' defined in assembly 'WPFXbapClient,
[...snip...] ---> System.Security.SecurityException: Request for the permission of type
'System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089' failed.
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.Net.CredentialCache.get_DefaultCredentials()
at System.Web.Services.Protocols.WebClientProtocol.set_UseDefaultCredentials(Boolean value)
at WPFXbapClient.Service1Proxy.Service1.set_UseDefaultCredentials(Boolean value)
at WPFXbapClient.Service1Proxy.Service1..ctor()
at WPFXbapClient.Page1..ctor()
The action that failed was:
Demand
The type of the first permission that failed was:
System.Security.Permissions.EnvironmentPermission
The first permission that failed was:
<IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089"
version="1"
Read="USERNAME"/>Now, we can't expect an Internet-zone application to be given access to the system environment. So why does the web service proxy try to go there? set_UseDefaultCredentials is the first useful clue. The second one comes as a big surprise, but fortunately it was easy enough to find it with the help of IntelliSense. First, jump to the ctor of the (generated) proxy:
public Service1() {
this.Url = global::WPFXbapClient.Properties.Settings.Default.WPFXbapClient_Service1Proxy_Service1;
if ((this.IsLocalFileSystemWebService(this.Url) == true)) { //*** <--- SUSPECT!
this.UseDefaultCredentials = true;
this.useDefaultCredentialsSetExplicitly = false;
}
else {
this.useDefaultCredentialsSetExplicitly = true;
}
}
Next, IsLocalFileSystemWebService() has this [startling!] condition:if (((wsUri.Port >= 1024)
&& (string.Compare(wsUri.Host, "localHost", System.StringComparison.OrdinalIgnoreCase) == 0))) {
return true;
Aha, mystery solved! Your XBAP accesses the web service at http://localhost:1749/Service1.asmx (set in app.config). It's clear that you may want to do testing with a non-standard port, but apparently not every magic number works equally well... After I switched to port 80, the XBAP finally started ... well, after me waking up to the last (minor) issue...[3] The Publish feature in Visual Studio takes you to a publish.htm page that lets you easily launch the published application. Unfortunately, it substitutes 'localhost' with the actual name of your computer in the URL to the XBAP, as in http://changov4/WPFXbapClient.xbap. If you start the XBAP via the publish page, you'll get a site-of-origin discrepancy, with a SecurityException from the HttpWebRequest constructor.
In your project, instead of hard-coding the address of the web service, you could perhaps construct it based on the site-of-origin of the XBAP (BrowserInteropHelper.Source). This would be more flexible in general, but in particular it would overcome the problem with the publish page.
After all that, your XBAP & web service actually work without change. :-)
- Thanks Chango.
BrowserInteropHelper really helps me. - Hello,
I have the same problem but working on IIS 6 for the moment
There is no web.config in this version but Metabase.xml
Could you help me
Thanks,
Nicolas
Sid


