serialization question

D

DBC User

I have a binary serialized file on the client box. I would like to
open it with a completly different program to see what is in it. I
copied the the serialized class information from the project which
created it to a new project which will open the serialzed object. When
the program ran I got a run time error stating, I will not be able to
open the serialized object since it was created by a different dll or
namespace.
Is it possible to do this?
Thanks.
 
K

Kevin Spencer

Sure. Put the serializable class and the serializer class into a class
library, and use that in both projects.

--
HTH,

Kevin Spencer
Chicken Salad Surgeon
Microsoft MVP
 
N

Nicholas Paldino [.NET/C# MVP]

That's not going to work, since that serialization engine is going to
look at the type of the object that is serialized.

By moving the class file to another assembly, you are effectively
creating two separate types, and serialization will fail.

You could do this and create a ISurrogateSelector implementation which
will select the correct types to serialize/deserialize.

However, the easy way to do this would be to separate the class into a
separate assembly, and then reference the assembly from both programs. This
way, you have ^one^ definition of the type.
 
P

Peter Duniho

[...]
However, the easy way to do this would be to separate the class into
a
separate assembly, and then reference the assembly from both programs.
This
way, you have ^one^ definition of the type.

This is, as near as I can tell, what Kevin meant when he wrote "into a
class library".

I didn't read his post to mean copying the code for the serialized class
into each place it will be used, but rather to move it into a separate
assembly just as you've suggested here.

Pete
 
N

Nicholas Paldino [.NET/C# MVP]

Yeah, I read it too fast, I read it as putting the class in each
assembly.

- Nick

Peter Duniho said:
[...]
However, the easy way to do this would be to separate the class into
a
separate assembly, and then reference the assembly from both programs.
This
way, you have ^one^ definition of the type.

This is, as near as I can tell, what Kevin meant when he wrote "into a
class library".

I didn't read his post to mean copying the code for the serialized class
into each place it will be used, but rather to move it into a separate
assembly just as you've suggested here.

Pete
 
D

DBC User

    Yeah, I read it too fast, I read it as putting the class in each
assembly.

        - Nick




On Thu, 10 Jan 2008 08:22:36 -0800, Nicholas Paldino [.NET/C# MVP]
[...]
    However, the easy way to do this would be to separate the classinto
a
separate assembly, and then reference the assembly from both programs.
This
way, you have ^one^ definition of the type.
This is, as near as I can tell, what Kevin meant when he wrote "into a
class library".
I didn't read his post to mean copying the code for the serialized class
into each place it will be used, but rather to move it into a separate
assembly just as you've suggested here.
Pete- Hide quoted text -

- Show quoted text -

Thanks all for the answer. In this 'particular' situation I need a way
to read it without mixing and creating a dll/lib to use it. Sorry.
This is a very peculiar situation. Hopefully as suggested
ISurrogateSelector might help me. I never used it. I need to google it
to find out more about it. If any one has any sample code, please let
me know otherwise thank you for the comments and suggestions.
 
N

Nicholas Paldino [.NET/C# MVP]

I have to ask, why can't you use a separate assembly dll? It seems like
a silly requirement.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Yeah, I read it too fast, I read it as putting the class in each
assembly.

- Nick




On Thu, 10 Jan 2008 08:22:36 -0800, Nicholas Paldino [.NET/C# MVP]
[...]
However, the easy way to do this would be to separate the class into
a
separate assembly, and then reference the assembly from both programs.
This
way, you have ^one^ definition of the type.
This is, as near as I can tell, what Kevin meant when he wrote "into a
class library".
I didn't read his post to mean copying the code for the serialized class
into each place it will be used, but rather to move it into a separate
assembly just as you've suggested here.
Pete- Hide quoted text -

- Show quoted text -

Thanks all for the answer. In this 'particular' situation I need a way
to read it without mixing and creating a dll/lib to use it. Sorry.
This is a very peculiar situation. Hopefully as suggested
ISurrogateSelector might help me. I never used it. I need to google it
to find out more about it. If any one has any sample code, please let
me know otherwise thank you for the comments and suggestions.
 
P

Peter Duniho

Thanks all for the answer. In this 'particular' situation I need a way
to read it without mixing and creating a dll/lib to use it. Sorry.

I agree with Nicholas...that seems like a silly requirement.

However, if that is indeed your requirement, you'll have to write your own
serialization, something that's not tied to the .NET class the way the
built-in is.

Pete
 
M

Marc Gravell

One cheap option here - use xml serialization. DataContractSerializer,
for example, can be used with "preserver references" enabled to
properly serialize the object *graph* (not the object *tree* that
XmlSerializer would produce) - just wihout the assembly information
that is plaguing you. It would also be trivial to parse, transform,
etc.

If you are concerned about space (for big graphs), then another easy
trick is to chain a GZipStream.

An illustration (demonstrating DataContract working on a graph with
loops, and working through GZipStream):

[DataContract]
public class MyData
{
// simple values
[DataMember]
public int SomeValue { get; set; }
[DataMember]
public string SomeOtherValue { get; set; }

// to prove object graph
[DataMember]
public MyData Sibling { get; set; }
}
class Program
{
static void Main()
{
MyData a = new MyData { SomeValue = 4, SomeOtherValue =
"abc" },
b = new MyData { SomeValue = 6, SomeOtherValue =
"def", Sibling = a };
a.Sibling = b; // make a closed loop...

DataContractSerializer dcs = new DataContractSerializer(
typeof(MyData), null, int.MaxValue, true, true, null);

// write
using (Stream zip = new GZipStream(
File.Create("test.bin"), CompressionMode.Compress))
{
dcs.WriteObject(zip, a);
zip.Close();
}

// read
MyData c;
using (Stream zip = new GZipStream(
File.OpenRead("test.bin"),
CompressionMode.Decompress))
{
c = (MyData)dcs.ReadObject(zip);
}

Console.WriteLine("{0}, {1}\t{2}, {3}\t{4}",
c.SomeValue, c.SomeOtherValue,
c.Sibling.SomeValue, c.Sibling.SomeOtherValue,
ReferenceEquals(c, c.Sibling.Sibling));

}
}
 
M

Marc Gravell

I forgot to say; the point of a DataContract is that you can load it
simply with a matching contract (i.e. copy/paste) - it doesn't care
about specific assemblies etc.

Marc
 
N

Nicholas Paldino [.NET/C# MVP]

And the XML will not work because the file is ^already^ serialized from
another program.

Using a DataContractSerializer ^might^ work, as the
DataContractSerializer does honor classes that are tagged with Serializable
and follows the same semantics as it, but there is no guarantee that the
format will be compatable with what the BinaryFormatter produces (as a
matter of fact, I'd be very surprized if it did).
 
M

Marc Gravell

[Nicholas Paldino]> And the XML will not work because the file is
^already^ serialized from another program.

Ah - right, misunderstood. Yes, if the OP *already* has the serialized
file, then, well, it gets very tricky.

My reply was to "if I am /designing/ a system that (as a requirement)
must be able to do this..." - in which case a data-contract is a
perfectly viable solution - but no, it absolutely won't allow you to
read output from BinaryFormatter...

But then, the same applies to your own suggestion of using a shared
assembly from both projects - it is presumably already too late to
change the one that produced the existing file.

Marc
 
D

DBC User

[Nicholas Paldino]> And the XML will not work because the file is
^already^ serialized from another program.

Ah - right, misunderstood. Yes, if the OP *already* has the serialized
file, then, well, it gets very tricky.

My reply was to "if I am /designing/ a system that (as a requirement)
must be able to do this..." - in which case a data-contract is a
perfectly viable solution - but no, it absolutely won't allow you to
read output from BinaryFormatter...

But then, the same applies to your own suggestion of using a shared
assembly from both projects - it is presumably already too late to
change the one that produced the existing file.

Marc
Thank you very much again. Since you have asked the requirement, here
is what is happening. We have a massive project which does all these
work and I do have these serialised object in a seperate dll. Now I
got a special request from one of a biggest client, they want to
update this serialised object in all their install with specific
information. I do have an option on the GUI to update the serialised
object. But client said, users tend to make mistake and the IT
department want to update it through back door, by asking all the
users in the company to run a program from network and 'this' program
will read the clients serialised object and update it.
So here is what I went about, I created a program referenced the dll
to update the object and everything worked ok. I signed the
application with the certificate and ran a test in one of our server,
dll failed with security exception stating the dll doesn't have enough
security and has to be given full trust. Now I ran a caspol on it
manually and it worked. I could have added the caspol command in a
batch program and let the client run the batch program, where the
caspol runs first then run the actual program. But the server location
where I need to point to the dll can not be hardcoded since there are
multiple server location the clients could point to. So I thought, if
somehow I can access the serialised object through the main program
instead of the dll I could resolve the problem without running caspol.
This is my story :(
 
B

Bilz

This is my story :(

Assuming you already have the serialized file but you don't have
access to the DLL that created it, your only real option is to write a
tool that parses the binary file directly! Yuck.

I have written a similar tool in the past... I HACKED the binary file
to change the values by using the BinaryReader and BinaryWriter class.

I hate this type of code... I despise it, really... but sometimes it
is the only way.

B
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top