Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF REST service - DataContract stops constructor?

I have a strange problem that's happening with my WCF REST service. For an operation where it accepts data, let's say it accepts the Foo class:

[WebInvoke(Method = "PUT", UriTemplate = "users/{username}")]
[OperationContract]
public void UpdateLoginUser(string username, LoginUser userUpdated) {
[...]
}

Now my LoginUser class inherits from my NormalUser class:

<DataContract()> _
Public MustInherit Class NormalUser
[...]
End Class

Public Class LoginUser
 Inherits NormalUser
[...]
End Class

When I PUT to my service, triggering UpdateLoginUser, everything works OK. However, if I apply DataContract to my NormalUser class:

<DataContract()> _
Public Class LoginUser
 Inherits NormalUser
[...]
End Class

... suddenly, the LoginUser class's constructor doesn't fire during deserialization! I have business login rules in there I need to run. So, why is it that when I apply the DataContract attribute to my inherited class, its constructor stops getting fired? How can I get around this? If I want to change namespace or name, I do need to apply the DataContract attribute.

like image 997
Jez Avatar asked Sep 29 '09 14:09

Jez


2 Answers

DataContractSerializer does not call the contract's constructor. If you want a method to run upon deserialization decorate it with the OnDeserializing attrbute:

When applied to a method, specifies that the method is called during deserialization of an object.

Your other option is to use XmlSerializer with WCF:

WCF also supports the XmlSerializer class. The XmlSerializer class is not unique to WCF. It is the same serialization engine that ASP.NET Web services use. The XmlSerializer class supports a much narrower set of types than the DataContractSerializer class, but allows much more control over the resulting XML and supports much more of the XML Schema definition language (XSD) standard. It also does not require any declarative attributes on the serializable types. For more information, see the XML Serialization topic in the .NET Framework documentation. The XmlSerializer class does not support data contract types.

like image 104
Andrew Hare Avatar answered Sep 23 '22 02:09

Andrew Hare


The DataContract (de)serializer does indeed NOT call the constructor.

That sounds odd and crazy - but that's the way it works, and there is no way to change this.

Because of this, the DataContract serializer also does NOT require a parameter-less constructor (like XmlSerializer or others).

Marc

like image 20
marc_s Avatar answered Sep 26 '22 02:09

marc_s