I have developed a full-trust WPF XBAP application using the Csla.Net framework that runs fine in IE6, IE7, and IE8. However, when I attempt to use IE 9 I get the following error:
System.Runtime.Serialization.SerializationException: Unable to find assembly 'Csla, Version=188.8.131.52, Culture=neutral, PublicKeyToken=93be5fdc093e4c30'.
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String memberNames, BinaryTypeEnum binaryTypeEnumA, Object typeInformationA, Int32 memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.DeserializeObject(MemoryStream stm)
at System.AppDomain.Deserialize(Byte blob)
at System.AppDomain.UnmarshalObject(Byte blob)
I've made sure the security certificate is imported into the Trusted Publishers and Trusted Root Certificates stores, the site has been added as a trusted site, and the "XAML browser applications" IE security option is enabled. I've also verified I can run XBAP applications in IE 9 that don't contain Csla.Net.
Is there something specific I need to do for CSLA.Net to work within a full-trust WPF XBAP in IE9?
XBAPs are just a PITA. Total PITA. They tried to emulate the worst aspects of the web with that technology - yuck!
If you insist on using an XBAP (where I think you should really use Silverlight - which works much better), you need to understand what the XBAP framework is doing to you (not really for you, but to you).
Each time you do a page transition, the XBAP works very hard to ensure that nothing remains in memory from the previous page. It appears they do this by creating a new AppDomain for each page - or they clean the AppDomain to a degree I've never seen before. This takes what would be a smart client technology and dumbs it down to being at least as bad as the stateless web.
Also, XBAPs are hosted in IE, and so aren't hosted by a normal, native .NET environment. This messes with the .NET serialization model. The same effect occurs in IE, COM+, and other non-managed hosts.
Specifically, any types from dynamically loaded assemblies (assemblies loaded via reflection instead of static binding), are not found during deserialization like they should be. Many years ago I tried to argue that this was a bug. But even if it is a bug, the issue is at such a low level, near the core of the .NET runtime itself, that changing it now is unrealistic I'm sure.
To overcome this serialization issue, you need to establish a hook at the AppDomain level to "help" the .NET serialization model work properly. Basically, you set up an event handler that is invoked when the runtime can't find a type. In your event handler, you look through the list of known types, and return the one that the runtime couldn't find.
Behind the scenes it turns out that .NET maintains (iirc) 4 different lists of known types. The one you can get from the AppDomain object is a consolidated list - so we see just one list. But there are really 4. And for some reason the dynamically loaded list isn't used when .NET is running within a non-managed host.
The Enterprise Service data portal channel has this code - look at older versions of CSLA .NET. Or look at CSLA .NET 1.0, specifically at a utility I included back then to run .NET apps from a network shared drive. That also includes this code.
Firstly, thanks for the response. It turns out this was a stupid permission problem with the user account and the backend database. That's totally my bad.
In general though it has been a pain to work out all the security aspects of the XBAP. The main reason we went with full-trust XBAP was so it could access local resources on the user's PC. We need to save files to their local hard-drive for data export features, etc. Though certainly no expert, I thought Silverlight was a sand-boxed architecture using WPF and would always run in a partial-trust mode in the browser. Can I access local resources with Silverlight? Would I just make the silverlight component full trust or something similiar?
There are several options:
Silverlight 3 can run out-of-browser. Silverlight 4 allows COM interop. Silverlight 5 has p/invoke (they just put out the release candidate for SL5).
Personally, my speculation is that WPF has a limited life, because Silverlight is moving so much faster, and is core to Windows Phone and Windows clients. But that's editorial thinking on my part :)
I am having a similar issue to what this thread is describing. After reading your reply, I am very much hopeful that there may be a solution, but I was wondering if you could give me a little more direction. My issue is as follows:
I have a Win Form control that I want to host in internet explorer. I have the assembly for this control marked as com visible and all the proper attributes and decoration for com visibility. When I install the control on a client (via msi), it renders perfectly in internet explorer. The control gathers data by making WCF calls to a server. The calls succeede (I can verify the requests are received at the server), but when the results come back, the result objects are not able to be deserialized by the IE process (even though the assemblies for the corresponding classes are loaded into memory).
This sounds very similar to what you're describing in this post regarding the running process not knowing what to do about deserialization. I would like to try your approach regarding "Helping the framework figure out what to do" but I'm not sure of the approach. I'm not sure if I can catch the unhandled app domain exceptions as my code is only a .NET control, and I don't have much control over the IE process. Any direction you could provide would be much appreciated.
One example of the code is here:
Search for "workaround" and you'll see the code bits necessary.
The serialization workaround is an ancient issue - svn shows the date as 2003 or 2004, but I'm pretty sure I actually wrote this originally in 2001 or something :)
That worked!!! Thank you so much!
Copyright (c) Marimer LLC