Constructor in WCF DataContract is not reflected on the client

I need some data members to get some values ​​when I instantiate a DataContract on the client. This does not happen with the help of constructors. I went through various forums and found that we should use the [OnDeserializing] and [OnDeserialized] attributes. This also does not work. Can someone suggest something here. Another alternative is to create constructors in partial classes on the client side. I want to avoid this.

Enter the code below:

Server Side: Datacontract

[DataContract] public class Account { private int mAccountId; private string mAccountName; public Account() { mAccountId = 5; mAccountName = "ABC"; } [OnDeserializing] public void OnDeserializing(StreamingContext context) { mAccountId = 5; mAccountName = "ABC"; } [OnDeserialized] public void OnDeserialized(StreamingContext context) { } [DataMember] public int AccountId { get { return mAccountId; } set { mAccountId = value; } } [DataMember] public string AccountName { get { return mAccountName; } set { mAccountName = value; } } } 

Client side - initialization

 namespace TestClient { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Account acc = new Account(); } } } 
+8
wcf datacontract
source share
2 answers

The code generator used to create WCF proxy classes creates compatible contract types and does not use the same type as the WCF service uses. The easiest way to achieve what you want is to create a constructor yourself on your client, as the generated code is partial :

 partial class Account { public Account() { AcountId = 5; AccountName = "ABC"; } } 

If you do not want to do this, you can force WCF to reuse the types that your client project already refers to. Therefore, if your data contract classes are in a separate library (as recommended), you can reference this library and then reconfigure your WCF client project to reuse common types from the reference assembly.

+14
source share

The properties associated with the DataMember attributes only determine what will be included in the generated WSDL / XSD. The client will generate its own wsdl / xsd based classes for use with the service. It does not use the same classes that are used on the server.

This is why you will not get:

  • any constructors defined in the DataContract class
  • any private [DataMember] properties / fields (the client will always generate public properties / fields)
  • any behavior defined in the DataContract class

Imagine a scenario when a java client wants to connect to your service. Do you expect Java classes to be generated using the same constructor? What about the [OnDeserialized] attributes? What about a java script client or python client?

When you start thinking about it this way, you begin to understand why you cannot have what you want (at least not exchanging libraries between the client and server).

The reality is that you cannot force the client to have classes that always have default values, and you cannot always send valid data back to the client, the client can always just send a message containing garbage if it wants. You have little control over some aspects of the message using IsRequired and 'EmitDefaultValue`, which will add checks in xsd to make sure that something is present in the message, but you will need to perform a check on the server, you can assume that you are returning objects will be checked.

My suggestion was to create a DTO from your domain objects to send over wires that do not contain any verification, they are just simple packages for storing data. Then create factories to turn your domain objects into DTO and DTO into client objects. factory simply accepts a DTO and passes members to the constructor of the domain object. Then your validation logic can live in the constructor of the domain object where it belongs. With the approach that you are currently using, you probably end up twisting the test slightly so that it can be performed both from the constructor and from the [OnDeserialized] method.

+13
source share

All Articles