I need to have some data members get some values when I create an instance of the DataContract on the client. This is not happening using constructors. I have searched throu
The code generator used to create WCF proxy classes creates compatible contract types, and doesn't used the exact same type as used by the WCF service. The easiest way to achieve what you want, is to create the constructor yourself on your client, as the code generated is partial
:
partial class Account
{
public Account()
{
AcountId = 5;
AccountName = "ABC";
}
}
If you don't want to do this, you can get WCF to reuse types that are already referenced by your client project. So if your data contract classes are in a separate library (as is recommended), you can reference that library and then reconfigure your WCF client project to reuse the shared types from the referenced assembly.
make Proxy class in your client side:
public class AccountProxy: Account
{
public AccountProxy()
{
mAccountId = 5;
mAccountName = "ABC";
}
}
and use your proxy class, not generated client class:
namespace TestClient
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
AccountProxy acc = new AccountProxy();
}
}
}
The properties attributed with the DataMember
attributes only define what will be included in the generated WSDL/XSD. The client will generate its own classes based on the wsdl/xsd to use for communication with the service. It does not use the same classes which are used on the server.
This is why you will not get:
DataContract
class[DataMember]
properties/fields (the client will always generate public properties/fields)DataContract
classImagine the scenario where a java client wants to connect to your service. Do you expect the java classes to be generated with the same constructor? What about with the [OnDeserialized]
attributes? What about a java script client, or python client?
When you start to think about it in this way you start to see why you cannot have what you want (at least not without sharing libraries between the client and server).
The reality is that you cannot force a client to have classes which always have default values and you cannot for a client to always send back valid data, the client can always just send a message which contains rubbish if it wants. You have a little control over some aspects of the message with the IsRequired
and 'EmitDefaultValue` which will add checks into the xsd to ensure that something is present in the message, but you will have to do validation on the server, you can't assume that the objects you get back will be validated.
My suggestion would be to create DTOs from your domain objects to send across the wire, which contain no checking of any sort, they are just simple bags for holding the data. Then create factories to turn your domain objects into DTOs and DTOs into client objects. The factory simply takes the DTO and passes the members into 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 you currently have you will probably end up twisting the validation slightly so it can be done from both the constructor and in the [OnDeserialized] method.