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.
Related
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.
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.
So this seems like a fairly simple answer to a common problem: Infinite loop detected in Jackosn. If, when serializing an object tree, Jackson comes upon an object it has already serialized why doesn't it just ignore it? Is there a way to do this in Jackson, or has someone created something similar?
Why all this mucking around with JsonManagedReference/JsonBackReference, which is completely insufficent if you start serializing child objects (which need a reference to the parent) some of the time and you are serializing parent objects some of the time (which obviously doesn't want the child to refer back to itself)?
It seems like now I have to create custom views that take into account every type of circular reference and use case possible which in any non-trivial ORM is a huge task.
EDIT (October 2012)
Jackson 2.x actual now DOES support identity information handling with #JsonIdentityInfo annotation! So the original answer is bit out of date...
OBSOLETE
Jackson does not support handling of object identity: this is a non-trivial task not so because of identifying shared objects which can be done by traversing object graph (incurring some overhead), but rather in figuring out how to include identity information; which ids to use and how. This in turn is somewhat similar to inclusion of type information, but now adds second dimension of extra wrapping to handle.
Doing this has been requested before, and some thought has gone into figuring out how to do it, but ratio of effort to benefit (i.e. number of requests, how badly it is needed) has been higher than adding other features.
So your best bet is to use wrapper objects and implement this manually, or have a look at XStream which can solve this (when enabled; it adds significant overhead in time) and also has JSON output mode using Jettison.
Implementing this manually for your use case is bit easier than solving the general case: you could start with BeanSerializerModifier to add wrapper handler that can keep track of object identities, and know what to serialize instead as object id.
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.
Is there a way to hook into how specific types are serialized when using WCF and Silverlight. For example, I need to tweak how System.DateTime properties are serialized/deserialized.
Be careful here. Any time you change how something is serialized, you'll also have to change how the client deserializes it. You should have a very good reason in mind before changing how a data contract serializes, as they are made to be very interoperable. Anything you change could reduce the level of interoperability.
In your datacontract, use the [OnSerialized] attribute.
Since Silverlight doesn't support serialization callbacks (see here), you best bet might be to add a secondary property to any objects which wraps the DateTime property you need to control, and handle any "serialization" needs in that property.
Just a thought.