I've run into an apparent snag trying to reload an object created when we were using a different version of CSLA. The object was serialized to binary and saved in the database, but when I try to reinstantiate it, I get this error:
Could not load file or assembly 'Csla, Version=3.0.2.0, Culture=neutral, PublicKeyToken=93be5fdc093e4c30' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
We're using Csla 3.0.4 now, but I was surprised to see that just this minor upgrade could cause this.
Any thoughts as to why I might be seeing this? It looks like there may be some perils to just serializing things out of convenience that we hadn't anticipated.
(A potential side issue is that I don't even see how the object I'm restoring even would reference CSLA, since there are no CSLA base classes in it's parent hierarchy or of its members, but that's a another story).
No, but that's part II of the mystery. It's a very simple class with no parent in the CSLA framework:
[
Serializable()] public class CachedColumnList : List<CachedColumn>Neither class has anything to do with CSLA - these are U/I classes just for remembering how a user had arranged the width and order of columns in a grid. (CachedColumn has no base class).
You offer some good advice though. I guess if you want to serialize something that needs to survive version changes, that you need to write your own custom serialization instead of just relying solely on the binary serializer. Seems like a shame, though. :(
ajj3085:... Does your cached column class live in an assembly that references Csla? maybe it does store that...
At any rate.. the serialization is meant to move .Net objects across a wire, not for persistence. If you view serialization in that context, it makes sense. The version information is included because maybe in 1.0 there was FieldB, but in your next version of the assembly is 1.1, and FieldB is gone, and FieldC is now included. What's the serializer to do?Were you able to find the .config setting to ignore the version on deserialization? If the class hasn't changed, you should be fine.
Yes, the assembly itself references CSLA, so this was probably it.
Thanks for the insight -- I'm very glad I opened this can of worms early rather than once we had this in production.
In cases where I was using serialization for persistence, I was generally using a dictionary-derived class for the persisted data, that way it would just be a generalized Bag that I could put anything into it that I want.
I thought this would protect me from issues like this, but of course you could store any serializable class there, which opens up your FieldB, FieldC scenario with the contained objects. Back to the drawing board...
If you really have to find a way to persist, you can use (cannot
believe I am saying this : - )) data sets in conjunction with DataMapper
to populate them off the objects.
Sergey Barskiy
Principal Consultant
office: 678.405.0687 |
mobile: 404.388.1899
Microsoft Worldwide Partner of the Year | Custom
Development Solutions, Technical Innovation
From: rsbaker0
[mailto:cslanet@lhotka.net]
Sent: Tuesday, September 30, 2008 3:37 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] De-serialization error after minor CSLA upgrade
(3.0.2 - 3.0.4)
ajj3085:
... Does your cached column class live in an assembly that references Csla? maybe it does store that...
At any rate.. the serialization is meant to move .Net objects across a wire, not for persistence. If you view serialization in that context, it makes sense. The version information is included because maybe in 1.0 there was FieldB, but in your next version of the assembly is 1.1, and FieldB is gone, and FieldC is now included. What's the serializer to do?Were you able to find the .config setting to ignore the version on deserialization? If the class hasn't changed, you should be fine.
Yes, the assembly itself references CSLA, so this was probably it.
Thanks for the insight -- I'm very glad I opened this can of worms early
rather than once we had this in production.
In cases where I was using serialization for persistence, I was generally
using a dictionary-derived class for the persisted data, that way it would just
be a generalized Bag that I could put anything into it that I want.
I thought this would protect me from issues like this, but of course you
could store any serializable class there, which opens up your FieldB, FieldC
scenario with the contained objects. Back to the drawing board...
rsbaker0:I guess if you want to serialize something that needs to survive version changes, that you need to write your own custom serialization instead of just relying solely on the binary serializer. Seems like a shame, though. :(
This is absolutely true!! Microsoft recommends against using the BinaryFormatter or NetDataContractSerializer for any sort of persistence. These formatters should only be used for transient data, because the versioning consequences can be very serious if you change your assemblies while serialized data is outstanding.
Copyright (c) Marimer LLC