Why and when must we need to add "[Serializable]" attribute? - serialization

1) Besides for serialization from an object into a file/memory…… When must we add "[Serializable]" attribute?
2) Why must we add that? Why cannot we directly save the object into some known formation to the .NET library?
3) How can I tell in what sitatuations we must add this attribute? In what conditions?
Many thanks!

1) Besides for serialization from an object into a file/memory…… When must we add "[Serializable]" attribute?
When you want to serialize it, or an object that contains it, directly or indirectly, to any other medium, e.g. a socket, RMI, ...
2) Why must we add that?
Because that's the way they designed it. Security reasons spring to mind: you really don't want a password to be serializable by default for example.
Why cannot we directly save the object into some known formation to the .NET library?
Firstly because Serialization preceded .NET by several years; secondly there are various other ways of accomplishing that, such as SOAP.
3) How can I tell in what situations we must add this attribute? In what conditions?
You're just re-asking the same question here, two more times. You certainly need to do it if you ever get a NotSerializableException naming the class and the exception didn't indicate an inadvertent serialization of something you didn't intend to serialize in the first place.

Related

Best way of handling Jackson bi-directional references

I'm trying to build rest APIs for our core components using Jackson, and I had issues with some of the objects getting this exception:
javax.ws.rs.ProcessingException: com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError)
After searching I came out to know about several ways how to solve it.
e.g.
https://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
and I used the #JsonIdentityInfo which is working fine for me, but the question is WHAT IS THE BETTER WAY TO DO IT?
In this post:
Infinite Recursion with Jackson JSON and Hibernate JPA issue
There is a claim that need to use the #JsonIdentityInfo in caution cause it can cause problems:
In this case you've got to be careful, since you could need to read your object's attributes more than once (for example in a products list with more products that share the same seller), and this annotation prevents you to do so. I suggest to always take a look at firebug logs to check the Json response and see what's going on in your code.
I reached this article as well: http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html
#JsonIdentityInfo
I understood that #JsonIdentityInfo is newer approach in Jackson 2.
Advantage that it requires minimum code change (just to put this annotation in the problematic Object Model and no need to handle it from the other side.
A drawback is explained
#JsonIgnoreProperties
It requires to change more classes rather than just annotating the base one, and I'm not sure how it will will work if I have more than one class inheriting from that object model.

Is it possible to hook into the protobuf-net serializer to add some custom logic?

This may be overkill, but I am trying to reduce the network consumption of a client/server protocol, by having both sides keep copies of previously transferred URIs, so as to use 2-4 byte placeholders instead of the full URIs on subsequent chatter.
Problem is I think it will be quite expensive to reflect through all the complex objects being transferred to locate the URIs that need processing, whereas the serializer is already visiting all these fields and probably using a mechanism much faster than reflection.
Can this be done in protobuf-net?
If this is part of a single call to Serialize/Deserialize (i.e. your data has the same uri repeated at multiple locations), then you can already do this, simply by telling it to treat those strings as references (it has special handling of strings, so two different references of the same string contents count as equal):
[ProtoMember(7, AsReference=true)]
public string Uri {get;set;}
During serialization, the first time it spots a new string value (decorated with AsReference=true) it will generate a unique token to represent the string; all subsequent usages of that same string will serialize only the token.
If this is in separate calls to Serialize/Deserialize, then no: you would have to do it manually. I can think of some ways of doing it, but I think this would be better handled outside of the serialization layer.
Could you possibly customise the Objects that you are using that you want to Tokenise your URIs and have them inherit or implement an interface that you can check to see if that particular object is a Tokenizer.
Then if that's the case you might be able to use the BeforeSerialization / AfterDeserialization to make your transformations.

Does adding PetaPoco attributes to POCO's have any negative side effects?

Our current application uses a smart object style for working with the database. We are looking at the feasibility of moving to PetaPoco instead. Looking over the features I notice you can add attributes to make it easier to CRUD objects. Does adding these attributes have any negative side effects that I should be aware of?
Has anyone found a reason NOT to use these decorators?
Directly to the use of the POCO object instance itself? None.
At least not that I would be aware of. Jon Skeet should be able to provide more info because he knows compiler inner workings through and through, so he knows exactly what happens with this metadata after it's been compiled.
Other implications indirectly related to these
There are of course implications when accessing these declarative attributes, because they're read using reflection which is normally a slow process.
But there's nothing to worry here, because PetaPoco is a smart library and reads these only once then compiles & caches these things, so you only get penalized once then you get blazing performance afterwards. Because it uses compiled code.
Non-performance related implications
By putting attributes (any) on your classes/properties/methods you somehow bind your code to particular engine that will use this class, because they're directives for this particular engine to understand your code.
In case of PetaPoco attributes this means that your class can be used with PetaPoco but not with some other DAL (ie. EF) unless you add attributes of that one as well (EF Code First uses the very same approach with attributes).
The second implication is related to back-end database. In case you rename a table, column or any other part that is provided in your PetaPoco attribute as a constant magic string, you will subsequently have to change this string as well. This just means that you have to be thorough when doing database changes...
One downside is that it breaks the separation between the "domain" layer and the "data" layer, since it introduces the PetaPoco file (which contains data logic) to domain classes that should really not have any knowledge or dependency on the data layer.
If you're doing a single-project MVC app or something then it's okay to just use the Models directory for both, but for non-trivial and separated apps you'll have to have two PetaPoco files or play around with abstracting portions of the file in order to annotate your models without making them "know too much" about the underlying data, or else have you specify the table and/or primary key name all over the place.

When/Why should I not use IsReference=true on my DataContracts?

I understand what is the attribute property IsReference and what it is doing. But I don't understand why/when I should not use it. When is it a bad idea to use IsReference=true?
If my wcf service are .net to .net, is there good reasons to not set IsReference=true?
There are at least two reasons to avoid using IsReference:
First there is a performance penalty since all the serializer must perform an identity check for each object that is to be serialized.
Second, the DataContractJsonSerializer cannot serialize objects marked with the IsReference attribute. So if you need to support both Xml and Json then you cannot use it.
Apart from those, I don't see any reason not to use it. After all it does save some precious bandwidth!
I think that nothing bad should happen. If your graph contains more than one link to the same object instance, setting this attribute to true will reduce XML size.
http://zamd.net/2008/05/20/datacontract-serializer-and-isreference-property/
However I am not sure why it is not enabled by default.

Which types cannot be used for WCF?

I know for a matter of fact that Type cannot be used when passing in to a WCF service. Does anyone have a complete list?
I'm not sure anyone bothered compiling a list, and i'm not sure there is any use in compiling one. Instead, there are requirements that a type must meet in order to be used in WCF contracts. Mainly, it has to be serializable.
I think it is the programmer's responsibility to verify that the types used in contracts are all serializable, and to make sure all custom types are serializing and deserializing properly.
Anything that you want to use in a WCF service needs to be serializable first, and secondly, it needs to be able to be expressed using XML schema. Also, WCF is interoprable by nature, so anything that's too specific to .NET (like exceptions, the .NET Type and so forth) should be avoided.
Anything non-serializable is out from the get go, and anything that cannot be expressed in XML schema can't be used either. This includes interfaces - you can only use concrete classes - and it also exludes generic types, since XML schema doesn't know how to handle generic types.
You're quite okay as long as you stick to the basic types (int, string, datetime etc.) and anything that is directly composed from those types.
Anything not marked Serializable, for starters.