views:

184

answers:

4

A WCF service exposing multiple elements in DataContract as DataMember

[DataMember(IsRequired = true, EmitDefaultValue = false)]
public string Source;

[DataMember(IsRequired = true, EmitDefaultValue = false)]
public string Target;

In generated proxy (through add service reference in VS 2008) at client, the client can pass null or empty string in Source or Target. how can I enforce Source and Target as Required at client side. i.e. client should get an exception if Source or Target is set to null, before invoking the service call.

+1  A: 

Well, both null (xsi:nil) and an empty string are values - they just aren't values you want.

During deserialization (at client or server):

You could try putting some code in the setter to throw an exception for invalid values?

Alternatively (for more complex cases), I believe that data-contracts support deserialization callbacks, which should allow you to validate...

For example, you can add (in a partial class, if necessary, at the client):

[OnDeserialized]
internal void OnDeserialized(StreamingContext context)
{
    if (string.IsNullOrEmpty(Bar))
    {
        throw new InvalidOperationException("No Bar!");
    }
}

For pre-send checks (at the client), you would have to add an extra validation method, or perhaps (again, in a partial class):

[OnSerializing]
internal void OnSerializing(StreamingContext context)
{
    if (string.IsNullOrEmpty(Bar))
    {
        throw new InvalidOperationException("No Bar!");
    }
}

However, the server must also validate this - you can't assume that it is your client code that has sent the message.

Marc Gravell
so in what case IsRequired is actually applied? if the element is completely from the request xml?
Keivan
+1  A: 

The IsRequired attribute refers to the validation that happens on the data that is arriving on the wire. If you want validation done at the client side, you'll need to add code on the client side for that.

Darin Dimitrov
+2  A: 

You can't enforce anything on the client side. Think about it, a client can be custom developed by you, maybe not even in .Net like Java etc. IsRequired = true means that the type must have that member serialized over the wire, the value maybe be a null.

The only way is to throw a exception from you server if the value is null and use a proper fault contract.

If you control the client, you can absolutely add validation to get the error earlier (i.e. removing the roundtrip). You just can't (at the server) rely on it having been done.
Marc Gravell
In a SOA architecture I can never assume that I can control the client. That is why a well defined fault contract is a must. Otherwise you are correct.
A: 

You could also take a look at the Validation Application Block and how it can integrate into WCF:

http://msdn.microsoft.com/en-us/library/cc309334.aspx

MattK