Can I serialize an object if I haven't written the class used to instantiate that object?
I have a simple class
[Serializable]
public class MyClass
{
public String FirstName { get; set: }
public String LastName { get; set: }
//Bellow is what I would like to do
//But, it not working
//I get an exception
ContactDataContext db = new ContactDataContext();
public void Save()
{
Contact contact = new Contact();
contact.FirstName = FirstName;
contact.LastName = LastName;
db.Contacts.InsertOnSubmit(contact);
db.SubmitChanges();
}
}
I wanted to attach a Save method to the class so that I can call it for every object. When I entered the above statement containing the ContactDataContext I got the following error: In assembly ... PublicKeyToken = null 'is not marked serializable "
It is clear that the DataContext class is generated by framework (). I checked and didn't see where this class was marked with serialize .
What can I do to overcome this? What is the rule when I am not the author of a class? Just go ahead and mark the DataContext class as serializable and pretend everything will work?
thanks for the help
a source to share
The problem is that the field is db
getting serialized, although obviously it doesn't need to be serialized (it is created after the object is created).
Hence, you have to decorate it with the attribute NonSerialized
:
[NonSerialized]
ContactDataContext db = new ContactDataContext();
[Update]
To make sure the field is db
available after the object is initialized, you should use the lazy load property and use that property instead of the field:
[NonSerialized]
ContactDataContext db = null;
[NonSerialized]
private ContactDataContext {
get {
if (db == null) {
db = new ContactDataContext();
}
return db;
}
set {
db = value;
}
}
public void Save()
{
Contact contact = new Contact();
contact.FirstName = FirstName;
contact.LastName = LastName;
Db.Contacts.InsertOnSubmit(contact);
Db.SubmitChanges();
}
[Update2]
You can serialize most objects as long as it has a public parameterless constructor (or no constructor at all) and no properties / fields that cannot be serialized but requires serialization. If the class itself is not marked as [Serializable]
, you can do it yourself using a partial class. If a class has properties / fields that cannot be serialized, you can achieve this by inheriting from the class and overriding those properties / fields to decorate them as [NonSerialized]
.
a source to share
It might be worth taking a step back and seeing if what you want to achieve really is.
Typically, a serializable class is used to transfer data between two layers. This is most likely a simple class that only contains data.
It seems a bit out of place for it to retain the ability to persist the database. It is likely that both ends of the pipe actually have access to the database, and it seems unlikely that both will be able to store data.
I wonder if factoring is worth saving to the repository. So you have a repository class that will take a data transfer object, build a database object, and save it.
This will simplify your code and completely fix the problem you are facing. It will also greatly improve testability.
a source to share