I have a class generated by Linq2Sql:
public partial class BuyerOrder : INotifyPropertyChanging, INotifyPropertyChanged
I want to clone object of this class, like it's done in this post. For this purpose I define the partial class in not generated file, which I mark as serializable:
[Serializable]
public partial class BuyerOrder
But when I'm calling
formatter.Serialize(stream, source);
I'm getting an exception, saying that this class is not marked as serializable. What am I doing wrong?
If you want to serialize a LINQ-to-SQL type, then tell the code-gen to emit serializable data. You can do this in the DBML, or more simply in the designer - just set the serialization mode to unidirectional (this is the #Serialization attribute on the root <Database> element in the DBML).
This will generate attribute markers suitable for use with DataContractSerializer; LINQ-to-SQL is designed to be serializable with DataContractSerializer. It is not designed to be serializable with BinaryFormatter.
Every class derived from BuyerOrder must also be decorated as [Serializable], as well as all objects that the serializing instance holds a reference to (unless decorated as NonSerializable).
The exception should tell you the type that is missing the serializable attribute. If you can not or do not want to decorate all the classes you will need to get a little more creative.
-- The other possibility --
One option is to use the technique described in Implementing a generic deep-clone for C# objects. Since this can be done entirely in memory and without a binary formatter it will perform many times faster than serialization based cloning.
The source code is located at http://csharptest.net/browse/src/Library/Cloning
It only takes two lines of code:
using (ObjectCloner cloner = new SerializerClone())
fooCopy = cloner.Clone(foo);
Related
In my application I use a list of objects implementing my ISorter interface with exposes a single method void Sort(MyClass myClass)
So far ive created this list at the entry point on my application with a hardcoded set of ISorter implementations. Now im at the point where I'd like to be able to save and load this list from file.
I'd like the format to be XML so that it can be hand edited, but i discovered that .NET XMLSerializer class cannot serialize Interfaces. It can serialize a list of base classes, providing I mark the baseclass with the appropriate attributes:
[System.Xml.Serialization.XmlInclude(typeof(MyClassA))]
[System.Xml.Serialization.XmlInclude(typeof(MyClassB))]
class MyBaseClass
I dislike this, as it clutters my class with xml specific attributes, when i may wish to replace xml serialization with a different storage method later.
What is the downside to replacing my ISort interface with a SortBase baseclass, to facilitate serialziation? Is the use of an interface here wrong to begin with? Should i keep the interface, but implement it using a SortBase class from which all my other classes derive?
How could I abstract the storage so that the storage implementation could be changed later, and avoid decorating my classes with xml attributes?
Any additional information on best practices pertaining to datastorage/loading would be helpful
EDIT: The idea is that a user can create an text file (atm XML is preferred) specifying sorting operations which can the be loaded and applied to the data set.
EDIT2: I have, simplified, this situation
class Foo{
List<ISorter> MySorters
}
interface ISorter{
void Sort(MyClass myClass)
}
class SortByColor : ISorter{
public string SomeColorProperty{get;set;}
void Sort(MyClass myClass)
}
class SortByName: ISorter{
public string SomeNameProperty{get;set;}
void Sort(MyClass myClass)
}
Id like to pass my List to some storage/loading method which can create/load the list from some underlaying datasource ( for example an XML file)
EDIT3:
Ill probably end up using DataContractserializer, or XMLSerializer as this solves my issue, as long as i provide a common base class. I had expected there to be some more elegant way this could be handled, without polluting my objects with attributes
I have around 50 classes in polymorphic, inheritance relation. I used XmlSerializer to serialize them. Now for few classes I want to implement IXmlSerializable. So I started for one of class.This class not base class but derived directly from base class of all polymorphic relation.
After implementation, resultant XML contains tags only for above class which I have written in WriteXML method. There is no information for other classes. Very strange behavior!!!!
So please guide me to solve this issue, so that other classes information would maintain.
As I understand you correct - your xml contains properties that you implicit add in WriteXML (of current class)? But it is correct behavior. You should implicit add item as in example in description of interface.
If you need properties of base classes - add them. if you need properties of classes that inherit from this class - try to get them via reflection. Get Property Names using Reflection . But instead of typeof(MyClass) use .GetType() and check there how to get properties values.
Similar questions here and there.
End the ReadXml(XmlReader reader) method with the line
reader.Read();
seams to solves the problem...
I've got my fingers crossed that someone out there has a good understanding of the Microsoft XmlSerializer.
Basically, I have built a system for outputting XML on the back of the serializer which is now causing me a lot of hassle and I am trying to avoid a significant re-write.
Introduction
My current system employs a lot of derived classes.
For example,
BaseResponse -> CarParkResponse -> CarParkResponseInherited
BaseResponse and CarParkResponse (both in a library dll) are seperate from CarParkResponseInherited.
As a result, the base classes are ignorent of the derived class.
What I have done
-> Declared derived classes
I appreciate that in order for xmlserializer to do its thing, there are a number of ways to declare dervied classes.
Declare derived classes in base classes using XmlInclude
or
Declared types to be serialised and deserialised in xmlSerialiser. For example:
XmlSerializer serializer = new XmlSerializer(typeof(CarParkResponse), new Type[] { typeof(CarParkParameters), typeof(CarParkInformation) });
I have gone with the latter.
What I am trying to do
Because the derived classes are seperate and they share the same properties, what I am trying to do is serialize the dervied class as the subclass.
In other words deserialize CarParkResponseInherited as a CarParkResponse.
In "CarParkResponseInherited" I am using the declaration XmlTypeAttribute("CarParkResponse").
Initially this causes a problem when serialized
Types 'CarParkResponseInherited' and 'CarParkResponse' both use the XML type name, 'CarParkResponse', from namespace ''. Use XML attributes to specify a unique XML name and/or namespace for the type."
as the type is already in use "CarParkResponse" so I've declased XmlType("Response") in "CarParkResponse" to get around this.
The Problem
I am now trying to Deserialize the XML returned but I'm now getting the following problem.
The specified type was not recognized: name='CarParkResponse', namespace='', at OriginalRequest xmlns=''
Frustratingly the CarParkResponse is there. I am wondering if this is down to the fact I've used XmlType("Response") in the class and the serializer doesn't recognise the class as being type of CarParkResponse
So my question is
Basically is it possible to pass a derived class as a sub class and have it deserialized as the subclass using the XmlSerializer?
I have experimented with the xml produced.
For example, if I don't use the Serialization tags (such as XmlType() etc.) anywhere in my code. The xml produced will produce a carparkresponse element with "type" as an attribute.
The value is "CarParkResponseInherited". I have written some code that removes "Inherited" from the value which does allow it to be deserialized.
This approach is obviously not good so I am hoping there is a good way around this.
So...
if there is anyone out there that has had to patience to read through this post and can help or offer advice it would be most appreciated as I am all out of ideas.
Thanks.
It might be possible to do something using the XmlAttributeOverrides class. It's mostly used for specific property overrides, so it may or may not be the best thing for you.
The long way around would be to go ahead and serialize as the inherited class. Then, if the mappings are the same, deserialize the xml into the base class, and then, re-serialize into what you want.
Depending on how much or how little control you have over the assemblies, you could override the serialization on the inherited class so it does it as the base class.
I used DataContractSerializer to save user data but now
I want to use DataContext for my database design.
But the system existed struture as below cannot be stored through DataContext.
class Data
{
public DataType1;
public DataType2;
}
It seems these APIs cannot support storing user defined data type.
I don't want to separate all data members because this system uses these structure every where. If I changed the structure, it is hard to maintain and the DataType1 contains a List<> member. I don't know how to do even though separating
this structure.
Could you please kindly to give me some suggestions?
Thanks.
It seems these APIs cannot support storing user defined data type
If that were true the api would be completely without purpose.
The DataContractSerializer has what appear to be conflicting rules in an attempt to make serialisation more implicit. You can for example serialise a public type that has public properties and a public default constructor without having to decorate it with a DataContract attribute or any of its members with a DataMember attribute.
Looks to me that at the very least you need make Data a public class. Most likely you would need to review your other classes to ensure that either they are implicitly serializable or that you explictly mark them up with the DataContract and DataMember attributes.
Dear all:
But now I used DataContext
DataContext cannot serialize the user defined type even marked [Serializable].
The workaround seems to separate all the members into one class now.....
Thanks.
I have various classes which I want to expose as Complex Types in WCF, so I add [DataContract] and [DataMember] attributes as necessary on those types and properties.
However if I want to have them inherit from an abstract base class (for example Person inherits from abstract EntityBase), I get an error that the type "cannot inherit from a type that is not marked with DataContractAttribute or SerializableAttribute".
The problem is, if I add [DataContract] attribute to the base class, then that base class is exposed to the client via the WSDL. Not a huge deal I guess, but I would prefer my client doesn't know about my internal implementation.
If I add the [Serializable] attribute to the base class, then it seemed to work at first (it could be serialized but EntityBase was not referenced in the WSDL), but now if I add any properties to EntityBase then it will also complain that its properties are not serializable. (For example I add an ICollection then I get an error that RuleViolation is not serializable).
Unfortunately there seems to be no analogue to [IgnoreDataMember] for a [Serializable] type ([NonSerialized applies only to fields, not properties).
So basically I want to declare this base type but don't need any of its members to be serialized; is there any way to set this up in WCF so the client doesn't see this base type?
Did you try not marking your entities with [DataContract] and [DataMember] at all (so that default serialization is used) and instead marking base class properties with [IgnoreDataMember]?
You always have several choices and I'm afraid you will not like any of them.
Create a set of DTO objects and convert entities to DTO. This is generally a best practice if you want to hide your inner implementation.
Create a surrogate class (implement IDataContractSuroggate) for each entity so that you have control over serialization - I'm not sure if this avoids the problem.
Upgrade to .NET 4.0 and use EF with POCO classes (with no EntityBase as parent)
Best regards, Ladislav
I think you have to use the KnownType attribute.
For instance see WCF issues with KnownType for Dictionary
[EDIT] A more complete discussion of this problem and its solution can be found here:
WCF: Interfaces, Generics and ServiceKnownType