I make my windows communication service parameter optional (in Operation Contract), but on the client when I dont want to pass optional parameter, error happens and requires this parameter. How can I fix it?
Related
I have a WCF Service with a method that has 3 parameters: 1 input and 2 outputs. Eg.
Foo(input, out1, out2)
I add the service reference fine in my client code, however, when I go to call the service, visual studio doesn't recognise the parameters properly. I have to call the service as
Foo(out1, out2, input)
Why is this? I can see that the order is reversed in the reference file of the service reference, but if I change the order then visual studio gives me errors saying that they are not in the right order. Is this normal behaviour? Do I just need to call the service using the reversed parameters?
...when I go to call the service, visual studio doesn't recognise the
parameters properly
The problem you are having is by design.
When the service exposes the WSDL metadata to consumers, there is nowhere in the service definition where the service operation signature is maintained in its original form.
Instead, the input and output parameters are declared in separate collections.
Now, it's the job of the Add Service Reference tooling to make an attempt at reconstructing the original operation signature for consumers from the metadata, but in this instance it cannot. The original operation signature has been lost at this point. So it just reconstructs the operation processing the output parameters collection first, and then the input parameters, hence your observed behaviour.
The only way to make this go away is to:
not use output parameters in your service operation definition. This is recommended anyway, as output parameters are a code quality flag and should be avoided if possible, or
not expose metadata from the service. Consumers can call the service directly by using the actual service definition types using a WCF channel instead of using a service reference. This is generally regarded as being a superior method for calling a service in WCF.
Or you could just do nothing. The consumer is still able to call the service operation right?
I have adapted the WCF 'Stream' sample application that is provided by Microsoft to use a Request object that is set up in a Shared Assembly and decorated with the MessageContract attributes. This should then be passed in to the UploadStreamRequest() method of the service.
The problem is that when I add a service reference to the client and try to call the method, each of the properties of the MessageContract object have just been converted to separate parameters.
I have also experimented with the 'Always generate message contracts' option within advanced settings, and although this then changes the method so that it is passed a request object, it has regenerated its own proxy representation of the object (even though I have 'Reuse types in all referenced assemblies' ticked).
Can anybody explain what I am missing here?
Many thanks
I had this problem and I have fixed it ticking the checkbox "Always generate message contracts." when I add the Service Reference.
Hope this helps.
Is there a way to pass an optional parameter to a webservice, instead of having to overload the method?
If the webservice user is accessing the webservice directly, I want to do ActionA, if the user is accessing the webservice through my web interface, I want to do ActionA + ActionB.
no, you can't really have optional params for a service.
Even if an input parameter for a Web
service method is optional, you must
still include it and set the parameter
value to null
Supplying Web Service Method Arguments
So, its optional to a degree, that you dont have to supply a value, but you're still going to have to write null instead. Overloading is the 'normal' way to do this.
I'm developing a WCF service and if there is an error I want to serialize the incoming parameter from the original method that was called on the service. I am using IErrorHandler to catch all exceptions.
My initial thoughts were that I will store the serialized parameter in OperationContext.IncomingMessageProperties so that I can access it from the HandleError method. However, as this isn't run on the original thread I believe the OperationContext will be null, so I am considering accessing it from the ProvideFault method.
Does this seem feasible? And will it work with OneWay service calls?
Not sure I can really help you much here, but let me try:
on your client, your code basically calls a method and passes it parameters. The WCF stack on the client side then converts that into a SOAP message (typically with an XML body, but could be binary, too) with headers and all and then sends that message across the wire to the server to be processed.
The server then attempts to deserialize that message into an object and attempts to call a message on a server implementation object. That method on the server object will most likely have the same parameters again, as the client - however, there's a possibility that the call will fail before that method even gets called.
So what I'm trying to say is: you can't rely on the fact that your server-side method with its parameters really gets called - there might have been a problem with e.g. authentication, the message format, a missing header or something else, that causes the server side to fail and throw an exception even before the server-side method ever gets called.
In the end, in the IErrorHandler, there's no way I would know of to get a hold of the message and/or the method and its parameters - all you can get are the error that occured on the server, and you can use that to turn it into a SOAP fault.
What you could do - both on the client and the server side - is create a new behavior that plugs into the WCF stack, and that records the methods being called and the parameters being passed into them - by implementing a class that implements the IParameterInspector interface of WCF. But that only will get called if the message on the client and the server will get properly deserialized and the server-side method really gets called.
Check out some of these links for more info on WCF extensibility:
How to: Inspect or Modify Parameters
WCF Extensibility: Parameter Inspectors
IParameterInspector in WCF
Extending WCF with custom behaviors
Hope this helps a bit!
Marc
I've recently seen a WCF service declaring operation contracts with by ref arguments.
I don't know why this design decision was taken (operations are void), but furthermore, I'm not able - from my WCF knowledge - to say if this is a good practice or not. Or if this is not relevant.
What do you think?
However, According to this Microsoft Article a WCF Call behaves exactly like a Remote Procedure Call and ByRef arguments can be used to return data:-
http://msdn.microsoft.com/en-us/library/ms733070.aspx
Refer to the section: Out and Ref Parameters
In most cases, you can use in parameters (ByVal in Visual Basic) and
out and ref parameters (ByRef in Visual Basic). Because both out and
ref parameters indicate that data is returned from an operation, an
operation signature such as the following specifies that a
request/reply operation is required even though the operation
signature returns void.
WCF is not a "remote object call" method or anything - it's pure message-passing. So havnig a "by-ref" parameter might compile, but it's really not going to do anything useful.
On your client, you have a method with parameters which you call. The WCF runtime then intercepts that call, packages up the parameters and any further information needed into a message, serializes that message (into textual or binary XML), and send that message across the wire to the server.
The server then deserializes the messages back into a set of parameters, and the dispatcher component on the server will then instantiate the service class and call the appropriate method on that service class instance with the parameters from the message.
The whole story works backwards for the reply the server sends back.
But again: all you're exchanging between client and server is a serialized message - there's absolutely no point in making a parameter "by ref" - it cannot possibly be a by-ref parameter, in the end. The server and the client are totally separate worlds, totally separate objects and classes - they just look the same on the wire.
So I think whoever wrote that WCF method didn't understand the principles of WCF message passing, but was lured by the way WCF feels - like just a method call. But it's really not just a method call in the end.
i'm with marc_s.
you need to be very careful.
WCF will always assign a new instance of that object, it not just change its contents.
As mars_s already explained wcf is a messaging-framework.
Its nature is to send and receive indipendant messages.
I think a good practice is to always define an in-/ and an out-message.
Your sericve-interface will be easier to understand and maintain.
methods with ref- and out-parameters always tend to be very ugly and harder to understand.