views:

31

answers:

2

I'm working on a WCF Service. I have one service operation Function getValues(Optional verbose as Boolean) as List(of String).

This works:

' First, add a file reference that contains the iRM interface.
Dim ep3 As EndpointAddress
ep3 = New EndpointAddress("net.pipe://localhost/RM/RMPipe")
Dim netPipeRMClient As RMLib.iRM netPipeRMtClient = ChannelFactory(Of RMLib.iRM) _ .CreateChannel(New NetNamedPipeBinding, ep3)

dim foo as List(of String) = netPipeRMClient.getValues()

However, this does not work:

' Use Add Service Reference to get the client type... Dim ep3 As EndpointAddress
ep3 = New EndpointAddress("net.pipe://localhost/RM/RMPipe")
dim netPipeRMClient as RM.iRMClient = _
new RM.IRMClient(New NetPipeBinding, ep3)
Dim foo as List(of String) = netPipeRmClient.getValues()

On the last line, I get a compile-time error that says "Argument not specified for parameter verbose".

The verbose parameter was clearly defined to be optional in my method signature, but in my WCF service contract, it doesn't seem to be optional when I use the client created with "Add Service Reference".

Any ideas?

+3  A: 

Optional parameters are a .NET specific feature - WCF services are by nature interoperable, so you cannot rely on .NET specifics.

Anything you exchange in WCF is based on XML schema and WSDL. As far as I know, WSDL doesn't have any support for optional parameters. WCF and its underlying plumbing don't know about those things - so you cannot use them in WCF services.

You'll need to find a way to live without optional parameters in your WCF service calls.

There are a few additional things that WCF / SOA doesn't do well, that are totally ok in OOP/.NET - things like operator overloading, interfaces, generics etc. - you always have to take into account that WCF is designed to be an interoperable SOA platform, e.g. it must be able to talk to other languages and systems, like PHP, Ruby etc. - and some of those don't support all the niceties of .NET.

SOA and OOP are at odds sometimes - it's just a fact of life. If you want to use SOA and WCF (and I would strongly argue for that approach), then you'll need to be willing to "do it the SOA way" - even if that goes against what you could do in .NET and what OOP practices might suggest.

marc_s
This doesn't really make sense to me. To repeat, if I initialize my client using a file reference to the interface, I can use the optional parameter with my WCF client. If I initialize my client using "Add Service Reference", then I can't...
Rice Flour Cookies
@Rising Star: if you initialize your client using a file reference, you're basically "tricking" your way around the WCF runtime - you grab the .NET service contract and data contracts etc. directly. Add Service Reference does it the SOA way - after all, the service you're about to add a reference to could be a COBOL service on an IBM HOST - try explaining optional parameters to COBOL.....
marc_s
You could also use `Add Service Reference` to generate the proxy classes and then go back and modify the classes with the optional parameters. Just rememeber these changed would be lost if you regenerate the proxy.
Matthew Whited
A: 

If you are willing to use the ChannelFactory<...> instead of the Add Service Reference you could do something like this (reusing your existing service contract interface)

... Contract ...

[ServiceContract]
public interface IService1
{
    [OperationContract]
    string Echo(string input = "Default!!!");
}

... Usage ...

// you can still provide most of these values from the app.config if you wish
// I just used code for this example.

var binding = new BasicHttpBinding();
var factory = new ChannelFactory<IService1>(binding);
var endpoint = new EndpointAddress("http://localhost:8080/service1");
var channel = factory.CreateChannel(endpoint);
var resultDefault = channel.Echo();
var resultInput = channel.Echo("Input");
Matthew Whited