WCF IS One Way attribute - wcf

I am having a wcf method which has got isoneway attribute set to true.Now when i call this service from client ,service is throwing an invalid operation exception back to the client bcos of some business scenario going wrong.My understanding was that it will throw only endpointnotfound exception and timeoutexception.Can someone please explain why thats happening ?

Marking your contract as One-Way means exactly that: messages flow in one way only. Clients won't get an answer or wait for the service to execute at all, so there's no way that your client could possibly get a reply or fault from the service most of the time.
If you want that, then maybe a One-Way service isn't for you and what you really want is a two-way service with an empty reply (i.e. void)

Does the OneWay method return a value or has ref/out parameter? If yes, then that's the reason you are getting InvalidOperationException. This is expected behavior as per MSDN help for OperationContractAttribute.IsOneWay Property (http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.isoneway(v=vs.110).aspx).
Look for remarks section, it has following text:
One-way methods must not return a value or have ref or out parameters; otherwise a System.InvalidOperationException exception is thrown.
PS: I know it's too late to reply to the thread, but for someone like me who stumbles across the post after 3 years or so, it might be useful.

Related

IClientMessageInspector CorrelationState

I can't find much information on the return value for the BeforeSendRequest method of the IClientMessageInspector interface. All examples I've found always return null. From the description on MSDN, this method's return value is passed back as the correlationState argument once AfterReceiveReply is called. However, MSDN also states that the best practice is to use a GUID for the correlationState.
This statement is somewhat confusing to me as I am interpreting it to mean that I am supposed to use only GUIDs for the correlationState. What I want to do is use the xml content of the request as the state so that if the reply is a fault, I can log both the request and reply. I only want to log the request if the reply is a fault.
Does anyone have any experience with using the correlationState? Can I use it for what I want to use it for? It appears to work in testing but due to the limited amount of information I've found on this, I am worried that there may be some kind of pitfall that I'm not seeing.
The CorrelationState, as it's name, designed to help you to find the correlation between the sent request and the received reply.
Therefore, because GUID is a unique identifier, MSDN recommends to use it as the correlation state.
At the BeforeSendRequest and AfterReceiveReply methods you can log both correlation state value and Messages object (using CreateBufferCopy / CreateMessage and other Message class operations) and do the match between sent request and received reply.
Note that in this solution (and any other pure WCF solutions, BTW) you can't log the request only if the reply is fault. It's because there is no place in the WCF pipeline you have both request and reply.
The only chance to do so, as you mentioned, is to use the message (as string or Message object - again, using Message class operations) as the correlation state.
This is not necessarily a good idea if your service logic can got success reply and fault reply for the same input (for example if your logic depends on external resources as database or other service).

WCF: use or not to use exception from service to client in production? any alternative?

I am thinking in use some exceptions to from service to client.
I am thinking for example in this case. The client try to insert a register in the database. This register has a value for e filed that exists in the database, and how it has a unique constraint, when I do the savechanges I get an updateException.
I am thinking to use exceptions (faultException) to warn to client of the error, and use a custom class to send to the client the actual data of the register, so in this way the client does not to make other query for the register.
However, in this link, it says that exceptions only should be used in development, no in production, so, without exceptions, how could I do what I want to do?
Perhaps I could use a custom class, that have one list property for each type of entities, and a property bool, that indicates if the operation is right or wrong, other property with an arbitrary code to indicate the type of error... etc. This is a good alternative?
In summary, really is better avoid exceptions in production? how I could communicate to the client errors from the service?
You have 2 options:
Throw exceptions and return WCF faults
Attach error information to you return objects
I personally favour throwing exceptions and returning WCF faults. I dont like the idea of attaching error information to return objects, I feel it violoates object oriented principals. For example a field called 'ErrorCode' has no place on a 'CustomerAddress' object.
I believe that if exceptional circustances arise, then an exception should be thrown. This will also simplfy your code as you wont have to wrap everything in try catch blocks in order to attach error information to your return object. Although you may want to catch unexpected exceptions and then throw a more appropriate exception with a more useful message.

WCF Response Class Best Practices

I'm not sure if there's a best practice for Response Message in WCF. Could anyone please guide me to right direction please?
I've a BlaResponse Object with following attributes:
1. dateTime
2. sucessfailureMessage.
is there anything else I need to add e.g. number of errors, details of errors. Number of success correlationID etc etc?
Thank you in advance.
Why do you have such attributes. You must have some real requirement for introducing these parameters in your response - for example response grouping both successful and failed operations. If your response is just for single operation you should get rid of that and use exceptions for propagating faults.
WCF has very big support for typed exceptions - FaultContracts. You can create special FaultContract type for any expected exception and throw it with typed FaultException. Client can catch each expected exception separately and handle it.
It is generally considered good practice to hide technical details of errors, or any information that discloses details about the server / architecture from the clients (unless you are debugging of course), as this might compromise your security.
It really depends what you are doing, so I don't think I can say what additional info you might need without more information about your implementation. Even the standard Fault Contract is pretty much just a wrapper for your own custom data.

Exception while IsOneWay is True

I am new to WCF. I have a small question to ask.
Let's assume IsOneWay=true is set in for one of the OperationContracts in my service contract. Let's say when client calls this method and some exception occurs in the method what happens.
Besically I want to know when this property is set to true how the exception behaves.
Please reply.
Thanks in Advance
Sudhanshu
Depends on the type of error:
if it's an error in your actual service code, then nothing will happen, since the server cannot communicate back anything - the service operation just won't happen. The client channel will be in a faulted state for any future non-one-way call, i.e. unusable for future operations, so you'll have to recreate it to use it again
if it's a security or timeout error, the exception on the client will still happen - those aren't affected by the IsOneWay=true setting
Does that answer your question? If not: what do you need to know?

Problem with WCF client calling one-way operation

I have run into a problem when calling web service on a SAP PI bus from my WCF client.
The operation is defined as one-way, and the method on my proxy operation contract is decorated accordingly when the service reference is added.
However, the service client gets an exception when calling the according operation:
The one-way operation returned a non-null message with Action=''
Using SoapUI, the method on the bus can be called successfully, and it returns a SOAP envelope with an empty body. The bus people told me, this is according to the SOAP specs:
(SOAP specs, chapter 4.7.9, One-way operations):
There are differing interpretations of how HTTP is to be used when performing one-way operations.
R2714 For one-way operations, an INSTANCE MUST NOT return a HTTP response that contains an envelope. Specifically, the HTTP response entity-body must be empty.
R2750 A CONSUMER MUST ignore an envelope carried in a HTTP response message in a one-way operation.
R2727 For one-way operations, a CONSUMER MUST NOT interpret a successful HTTP response status code (i.e., 2xx) to mean the message is valid or that the receiver would process it.
So it seems, my WCF client doesn't comply with R2750.
I have found out that when I force the operation contract on the proxy to be IsOneWay = false, everything works.
Is there anything wrong with the way WCF handles one way operations or do I do something wrong (more likely)?
Is there anything else I should do, it just doesn't seem right to override the generated WCF proxy client.
Thanks for any suggestions.
It looks like SAP PI incorrectly sends an empty SOAP envelope and .NET incorrectly interprets that envelope.
Some options from this thread:
alter the generated proxy and remove OneWay=true (or add OneWay=false) to the method definition
catch the Protocol Violation in an exception handler and ignore it
use a 2.0 style webreference to call the service
apply SAP patch Note 1459995 - Soap Sender Adapter HTTP 202 and add &responsecode202=true to the url
The first and last options both worked for me. Further discussion on this sap.com thread.
I would take a look at this article as well by Gerben van Loon here. One way operation might not really be one way according to the standards.
Check this SAP thread out for the complete discussion:
http://scn.sap.com/thread/1627368
#Brian Low has answered this question correctly and very thoroughly (is should get marked as the answer).
I would also like to add that this is a known error in which the SOAP Adapter does not comply with the aforementioned WS-I Basic Profile 1.1 (R2750) and WCF does not comply with (R2750). The result... Hours of wasted time and teeth gnashing....
I believe that this particular problem can be fixed by adding the following attribute declaration to the operation in the client porxy:
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped)]
Without seeing what the signature of the method looks like, my best guess is that your method defined to return something other than "void". Since the operation is one-way, the method can only be defined using "void" (has no return). Anything else, and the operation is NOT one-way.