26

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.

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
kay.herzam
  • 3,053
  • 3
  • 26
  • 37
  • 2
    Great question +1. I'd argue their side does not comply with R2714 either. Please consider filing an incident with Microsoft and letting us know what the result is. – Jerry Bullard Sep 04 '09 at 19:41
  • Similar question (and more info): http://stackoverflow.com/q/4510484/46039 – Brian Low Feb 13 '13 at 18:33
  • Link to SOAP spec 4.7.9 One-way operations: http://www.ws-i.org/profiles/basicprofile-1.1.html – Brian Low Feb 13 '13 at 18:47

5 Answers5

17

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.

Brian Low
  • 11,605
  • 4
  • 58
  • 63
4

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.

Bryan Corazza
  • 829
  • 1
  • 7
  • 16
  • 1
    The semantics of oneway web calls over `SOAP` are comparable to `void()` not fire-and forget. Just like a method that returns `void()` the invocation is blocking and does have the capability of "returning" an exception. – Ethan Cabiac May 27 '11 at 18:00
1

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....

StuckOverflow
  • 991
  • 2
  • 10
  • 21
0

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)]

Ethan Cabiac
  • 4,943
  • 20
  • 36
  • Thanks for your answer. However adding this to the generated client proxy is about the same as setting the OneWay property to false. And unfortunately it didn't work. – kay.herzam May 30 '11 at 06:49
0

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.

Russ
  • 4,091
  • 21
  • 32