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.
Related
I built a number of WCF services as part of an application. Until recently, most of the classes that were used as parameters of the many operations in a service did not had the DataContract or DataMember attributes applied to them.
Now, I've made a few changes in a row and all of a sudden WCF is complaining that he can't serialize my classes.
Does anyone knows if any changes in configuration or even in the ServiceContract, OperationContract etc. can cause WCF to become picky about the classes it can serialize?
I'd rather not need the attributes in those classes (they should be pure C# classes as possible).
Also of note, if I return to a previous version in my source control, WCF goes back to "normal", so I believe that it's not a machine/environment thing.
The ability to create WCF Data Contracts without the use of the [DataContract] and [DataMember] attributes is a feature added to WCF in .NET 3.5 SP1. Since everything works for you when reverting your code to a previous version, I'm assuming you are already using at least that version.
Nevertheless, in order for classes to be serializable by WCF, the class must meet several requirements listed here. The main requirements of the data contract class are:
It must be public.
It must have a parameterless constructor.
It must not have any data members that do not meet all these requirements. If you do have such a member, mark it with [IgnoreDataMember] and it will be excluded from WCF serialization.
You can get more information about what fails to serialize by performing the serialization manually using the DataContractSerializer class. See this article for more details and code examples. Another method is to mark all members with [IgnoreDataMember] and gradually remove the attributes from members until serialization fails, which will tell you which member is causing the problem.
WCF is lenient towards classes that have [serializable] attribute. You don't require [DataContract]. You must have added something that is not serializable.
I know a way to do that. it's not professional but it works for me
I'm also need pure c# classes so I do it in this way.
I convert each parameter of my class to an object then gather them into array of objects and send it to the other side. in the other side I do the reverse operation to get my parameters back. but this operation will reduce the performance i think
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.
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.
We use custom type to represent Identifiers in our project. It has TypeConvertor attached and it always helped with serialization.
I've tried to use WCF Data Services to expose some data from our system, but faced a problem. Astoria framework do not recognize class as an entity even though I've decorated it with [DataServiceKey("Id")] attribute. If I change type of property to Guid - it totally works :(.
How could teach WCF Data Services to understand this simple class?
After a bit of research and a ton of Reflector work I've found that it's not possible.
WCF Data Services have monumental external metadata support described in detail by Alex James in very good series of posts.
However primitive data types creation is forbidden and key property of the entity should be of a primitive type. Moreover there is no pre- and post- execution hook available to provide run-time conversion from and to string type.
This and limited support of LINQ from NHibernate makes Astoria pretty unusable for me now. Witch is very sad.
As long as the class has a property Id DataServices should serialize it properly. You don't even need the attribute if the property is named ID. Did you see the example I did here. Also, you will find a complete list of OData related articles on http://www.Odataprimer.com. Maybe one of those will help.
Given the fact that I have a fully dynamic object model, that is, I have no concrete classes defined anywhere in code, but I still want to be able to create WCF DataContracts for them so I can use them in operations. How can I achieve this?
My concrete class "Entity" implements ICustomTypeDescriptor which is used to present the various properties to the outside world, but my expeimentation with WCF suggests that WCF does not care about ICustomTypeDescriptor. Is this correct or have I missed something?
Is this possible? It cannot be so that the only way to create a DataContract is to actually have a concrete harcoded class, can it?
you may use untyped service and message contract IIRC http://geekswithblogs.net/claeyskurt/archive/2008/09/24/125430.aspx
You might try System.Reflection.Emit.
Its quite tricky, but essentially you will just build a custom run-time type, with decorated data contract attributes. It gets tricky when creating encapsulated properties with PropertyChanged notifications, but in your service layer you can just get away with auto properties which are a lot easier.
This dated, but still very relevant link should get you going in the right direction.
http://drdobbs.com/184416570
Things evolve :-) Thanks to the excellent blog series by Alex D James its very easy to implement this.