I'm starting a new project on .NET 4. All the libraries I'll be creating will have SecurityTransparentAttribute applied.
Now I have an immutable struct in one of these assemblies that needs to be serialized. As an immutable object, there won't be setters for any property (like with System.DateTime).
If I simply mark the struct as [Serializable], nothing will be serialized, as the properties are readonly. The usual way to deal with this is to implement the ISerializable interface and take care of it in GetObjectData and the special constructor.
But in this case, my assembly will be security transparent, and ISerializable.GetObjectData is SecurityCritical, so I can't do it this way.
So, what are my options here? I would really like to have everything SecurityTransparent because I won't really need any critical stuff. Except this.
Thanks
If you're using BinaryFormatter, it serializes the fields of your struct, not its properties, and it works even if the fields are readonly. So if it's appropriate to serialize your struct by simply serializing its fields, you're all set.
My first thought is that is the knowledge of how to serialize itself too much behaviour to have in a struct?
You could go down the route of creating a type converter for it
Related
I need to binary serialize an object that contains a collection of lots of instances of some base class. Each instance could be any of the derived types, and there are really lots of possible derived types (around one hundred). Therefore I don't really want to modify each of these types so that this object could be serialized.
I would even like to avoid adding the default public constructor to all of these types as this would damage the architecture a little bit and would also be really annoying to do (and not really DRY), not speaking of adding Serializable attribute to every public property in these types. And for the same reason writing a custom serializer/surrogate for each of these types is hardly an option.
What I have tried so far:
BinaryFormatter - requires additional attributes for serialized properties
sharpSerializer - requires public default constructor
protobuf-net - requires addtitional attributes for serialized properties
Net serializer - requires addtitional attributes for serialized properties
I have also tried serializing with Json.NET and then saving the result as a byte array (I know, I know), but I ran into an OutOfMemoryException while serializing. This likely means my object is too heavy for text serialization (it takes around 200Mb in memory, but there are lots of elements in the array, lots of properties in each of the element etc).
If it makes any better - all the objects in the collection I need to save have only public properties (I don't need to serialize fields or private properties). And there also is no particular logic in these objects' constructors - only filling the properies.
Is there any way to achieve the serialization/deserialization without modifying the serialized classes?
I don't even know if it is possible to deserialize an object that does not have parameterless constructor (the restriction required by all of the serializers I've met), but it should be as the reflection allows to create instances without calling constructors.
i want to implement a general Memento-Pattern in C#. It is working fine but i use the Serializeable() Attribute to do a deep copy of a object. My implementation using generics so if someone use it he has to give his class as type.
Now the class from user must have the Attribute Serializeable() too. Are there any limitations for a class which using Serializeable()?
In fact:
Are there any performance problems?
Is it possible to use an interface?
Is it possible to use inerhitence?
Is it possible to use Auto-Properties?
I dont know how the Attribute works and so iam a bit scary of using this in such a global way.
regards
for small models that you are cloning in memory, not usually
irrelevent; when using [Serializable] you are typically using BinaryFormatter - which looks at the objects themselves; it doesn't matter what interfaces they implement - the interfaces are not used
yes, for the same reason - but all types in the model must be [Serializable]
yes, for the same reason; note : the default BinaryFormatter implementation is looking at fields - it won't even touch the properties
Personally, I try to advise against BinaryFormatter, but this is perhaps not an unreasonable use. However! Be careful that it is easy to suck extra objects into the model accidentally, must commonly through events. Note that it is a good idea to mark all events as non-serialized:
[field:NonSerialized]
public event EventHandler Something;
(or apply to the field directly if using explicit add/remove accessors)
Note also that any members like:
public object Tag {get;set;} // caller-defined
should also probably be [field:NonSerialized].
Personally, I'd prefer a different serializer, but: this will often work. I will say, though: try to avoid persisting the output of BinaryFormatter, as it is hard to guarantee compatibility between revisions of your code.
I dont know how the Attribute works
It does nothing at all except add an IL flag that says "by the way, consider this ok to be serialized"; actually, most serializers don't even look at this flag - but BinaryFormatter is one of the few that do look at this flag. The real code here is BinaryFormatter, which basically does:
have I seen this object before? if so, store the key only
what type is it? is it [Serializable]? store the type info
invent a new reference and store that as the identity
does it have a custom serializer? if so: use that
what fields does it have? access each in turn and store the name/value pair
Are there any closed or open source projects for a XML serializer for C# that can serialize for the most part any object without the need to pollute my domain objects with tons of attributes? That will also handle serialization of collections built with the internal generics classes? A bonus would be that it can handle serializing an interface type property. Another bonus would be that it can serialize objects that have read-only properties (or atleast with the get accessor marked internal)
Well, first define "advanced", i.e. what specifically do you need that XmlSerializer doesn't have. In terms of POCO, XmlSerializer has an overloaded ctor that accepts all the attributes you could ever want to add, to avoid having to add them to your object model - but it does still require a public parameterless constructor, and only works on public read/write fields/properties. And you should cache/re-use the serializer if you use this approach.
I'm not aware of any like alternatives, simply because in most cases this is "good enough" - and it is often a mistake to try to brute-force your existing domain object into a DTO. It may be simpler and more maintainable to simply map your domain entities onto a new DTO(s) that are attributed (and have appropriate ctor/properties/etc).
Note that for the ctor/properties issue DataContractSerializer has some answers, but this doesn't have as much fine-grained control over what the xml looks like.
You can allow System.Xml.dll to access your internals by using the InternalsVisibleToAttribute.
Thus serializing internal types and/or internal members. Including internal .ctors.
You can also implement IXmlSerializable on classes to customize their serialization (like the container containing interface references).
You do not have to provide the XML serialization attributes on your classes, but provide them as XmlAttributeOverrides instead.
XmlSerializer is almost always exactly what people want, they just don't know that it is as flexible as it really is.
I have data stored in an instance of a class which has been serialized with the .net BinaryFormatter. I now want to rename one of the fields in the class, but still be able to deserialize the old data.
One option is to implement ISerializable and deserialize all the the fields of the class manually. But this seems like a lot of work, especially if my class has lots of fields and I've only renamed a single field.
Is there a better way?
Craig suggests keeping a copy of the old class for deserialization, and copying values to the new class. I've seen this suggested elsewhere too - what advantage does this have over implementing ISerializable? As far as I can see, copying the class leaves me with 2 almost identical copies of the class plus I still have to copy all the values from the old class to the new class - which seems the same amount of work as implementing ISerializable with an almost duplicate class thrown into mix.
Two answers have mentioned Binders. I've successfully used a SerializationBinder to deserialize a class Bar which was Serialized as class Foo, but that's because the name of the class changed. Does SerializationBinder also help when you've renamed a field - say when int m_Left has been renamed to int m_Right?
Yes, this is the problem with field-based serializers. You can use either a custom Binder, or a "serialization surrogate" to avoid implementing ISerializable, but that is only a case-by-case fix.
I've discussed this topic (in the context of obfuscators, and auto-props) here. My advice is: don't use BinaryFormatter for persistance of data between versions... for that, look at contract-based serializers:
XmlSerializer
DataContractSerializer
or for binary, things like protobuf-net
None of this helps you today, but it might help you design around it in the future.
You could try having the old calss hang around for the sole purpose of rehydration and then just copy over the fields you need to the new class. Still kind of painful but should work.
I used SerializationBinder class for this before
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationbinder.aspx
it can be used for deserialization so you can remap old type to new one.
What if you just change the access modifier on that one property to private, and then have a public property with the new name that just basically wraps the old one. That way you should still be able to deserialize (I THINK) but anyone using this class won't know about the old name. Just a thought...
I'm looping through the Session keys and adding entries and their values to a Hashtable, which I'm then serializing. The problem I'm having is there is an object on the Session that is not serializable, and it shouldn't be serialized anyway. I'm looking around, and plenty of built-in types don't implement the ISerializable attribute, so testing for that doesn't work:
if (val is ISerializable)
{
...
}
So, how do I test for this? Does this make sense?
There is only one guaranteed way to determine if an object is serializable. Serialize it and see if the operation succeeds.
I know that seems a bit overkill but there are just so many different ways that serialization can be broken. There are two items in Metadata you can check to see if a type claims serializability (ISerializable and [Serializable]) but this is just a claim. It can and is broken in so many different ways.
The problem is that in the .Net world the act of declaring the ability to be serialized and actually serializing are 2 separate distinct actions. It's perfectly possible (and legal) to do one but not the other. Take this for example
[Serializable]
public class Foo {
public Object Field1;
}
This class claims to be serializable and may very well be. It all depends on the value actually stored in Field1. No amount of metadata inspection on the type will every tell you whether it can actually be serialized. All you can do is try and see if it suceeds.
You can use the IsSerializable property of the Type class.
if(val.GetType().IsSerializable)
Check the same thing that CRL would use: the [Serializable] attribute.