GZIP compress the request to a remote web service via WCF - c#

I'm writing an application using Visual Studio 2010 that needs to communicate with a remote web service. Because the amount of data being submitted is potentially large, (up to 100MB), the service's documentation says that the request message must be sent using GZIP HTTP compression.
My question is how to do that, given that I'm just calling a method on the proxy object that Visual Studio generated, and not actually performing the POST myself? In other words, since there isn't a "request" anywhere in my code to GZIP, how can I tell WCF to do it for me?
I've connected to the service by adding a service reference to my application using the WSDL provided, then invoking a method on the Visual Studio generated proxy to submit the request. An exception is thrown with the message "Request message must be sent using HTTP compression." (This is not unexpected, of course.)
Is there an attribute within the web.config settings that define the WCF service that will cause WCF to GZIP the request before sending it to the remote host?
Note: I've spent significant time searching the web about this, but the problem is that most posts assume that it's the web service's response that needs to be compressed. In my case, however, it's the request that's being sent from my client.

It seems like I have been able resolve this issue in a way that makes no sense to me from a "why does this even exist" way.
First, I was working on the same task as you: trying to use proxy objects to create a web request, and ended up running into the same issue being unable to compress the client object.
The resolution I ended up with was manually creating an XDocument object (XmlDocument would work as well) which has the same structure as the required SOAP XML, and then used the (already) populated proxy object to populate the necessary XML values in the string of SOAP XML.
From there I made a HttpWebRequest object and added the appropriate headers to the request. One of the headers was for compression. Executing the code resulted in getting an entirely different, non-compression related, error.
You can see my solution for the HttpWebRequest here: Compress a HttpWebRequest using gzip
It seems silly that it isn't easy to do through this the proxy object; however, it may be that the third-party did not expose what is necessary in order to add properties to the request header and either a.) they don't know or b.) they don't care, but that's what we have to work with, unfortunately.
I had to figure something out as I am on a deadline, but I hope this helps you out as well.

Have you tried adding <binaryMessageEncoding /> to the <customBinding /> element? I think we are working on similar tasks and I am also receiving the above FaultException. Two other SO topics led me down asking this question. It's something that makes sense, as I'm also not making a WebRequest through the code, but calling the service through the Service Reference created when I imported the WSDL provided by the third-party.
WCF custom binding for compression (a code-based approach)
and
WCF client endpoint compression (a configuration-based approach)
Let me know if you have any success with the above approaches.
Edit
An answer in the following thread indicates that unless you have control over the web service and the client, it might be something that can be done.
Using compression with C# webservice client in Visual Studio 2010
Edit #2
I think a few folks have been able to make progress in compressing a third-party service request using GZip. Please check out this post: Getting error for content mismtach while consuming client web service.
That post helped me get rid of the error message I was receiving (which was telling me that the request must be made using HTTP compression). I hope it helps you as well.
The request message must be sent using HTTP compression (RFC 1952 - GZIP).

Related

See WCF http data from Visual Studio

I am implementing the client-side of a ms webservice and i would like to see the exact http call that is made. i.e. all the parameters and how they are encoded.
I tried sniffing it with wireshark, but since it seems it is done via https i can see the data.
I am running this client straight out of visual studio. is there a way to see the data there?
Teletic Fiddler is great tool to debug any http communication. http://www.telerik.com/fiddler. I can show request and response information in raw views, xml, JSON etc
It can even inspect https traffic. Follow this guide.
There is a similar question here.

WCF Test Client that allows me to view/edit the request XML

From time to time we need to test why a certain request coming from our MQ to a WCF service failed. I need to be able to debug the service and find out where it went wrong and resolve the issue. The only information i have is the XML request that was sent to the service. Before we moved to WCF i used a custom tool to send the request to my ASMX debug instance but since we moved to WCF I dont seem to have that option. All the clients i have tried only allow you to fill in the fields through a UI and this is not an option when dealing with huge requests.
Is there a free or open source client that will allow me to do this? I have searched and tried loads but none seem to do it.
Alternatively is there a tutorial or article on writing a test client of this kind? Again i have searched but there seems to be a lack of information on WCF clients and a huge amount on the services.
tl;dr; Im looking for a WCF test client that will allow me to paste in an XML request and send it to a WCF service or a tutorial that will start me in the right direction.
Of course it is not free, but one of our teams is using Altova XMLSpy for that purpose and it works fine.
You can also check (Not sure they will allow you to edit SOAP, but have a try):
SoapUI
WCF Storm
Also check Web Service Studio 2.0 I have tried it will allow you to edit requests.
Not sure I totally understand what you're looking for:
to see the MSMQ messages, you should open the MMC snapin for MSMQ administration on your server where the MSMQ queues live - is that what you're looking for?
in order to create and send out arbitrary XML messages, have a look at SoapUI which is available in a free (and already very capable) version, or alternatively look at SoapBits

Will this web service accept both raw xml and an object?

We have a web service that provides auto insurance quotes and a company that provides an insurance agency management system would like to use the web service for thier client but they want to pass the web service raw xml instead of using the wsdl to create a port, the object the service expects and calling the web method.
The web service has performed flawlessly by creating an object like so
com.insurance.quotesvc.AgencyQuote service = new com.insurance.quotesvc.AgencyQuote();
com.insurance.quotesvc.QuotePortType port = service.getQuotePortType();
com.insurance.quotesvc.schemas.request.ACORD parameter = null;
Then create initialize the request object with the other objects that make up the response.
parameter = factory.createACORD();
parameter.setSignonRq(signOn);
parameter.setInsurancesSvcRq(svcRq);
And send the request to the web service.
com.insurance.quotesvc.schemas.response.ACORD result = null;
result = port.requestQuote(parameter);
By doing that I am able to easily marshall the request and the result into an xml file and do with them as I wish.
So if a client was to send the web service via an http post as raw xml inside of a soap envelope. Would the web service be able to handle the xml without any changes being made to the web service or would there need to be changes made to the web service in order for it to handle a request of that type?
The web service is a JAX_WS and we currently have both Java and C# clients consuming the web service using the method described above but now there is another client who wants to send raw xml inside of a soap envelope instead of creating the objects. I feel pretty sure that they will be making the call to the web service using vb.
I'm sure I'm missing something obvious but it is eluding me at the moment and any help is greatly appreciated.
I think you'd need separate URLs to handle this situation. You'd still map your WSDL and its endpoint as you're doing. But then you'd need to configure a second, separate URL that would have a servlet that accepted an encoded XML stream from the HTTP POST and dealt with that separately.
In theory, it should be possible to hand-build XML that is indistinguishable from the XML that is created by a conventional WS client.
In practice, getting this right in all of the edge cases could be rather difficult. And if they (the clients who send raw XML to your service) get it wrong, they are liable to get a lot of obscure errors ... and you may need to help them with diagnosing these errors.
In the worst case, malformed messages might impact on your system's performance. But one would hope that the WS middleware layers and your application are hardened against the effects of malformed requests.
In short, #duffymo's approach of creating a second API is less risk for you, though the cost is more up-front work for you. But the simplest approach would be to just say "No!".
Should be no problem since your wsdltojava and wsdltocsharp will just do that for you behind the scenes. As long as they follow the contract set out by the WSDL.
But it is a lot of work doing it manualy and completely unneccesary since there is also a wsdltovb thing which should be eassier for them. ANd they have to do it all over again when you change something on your side.
They are just reinventing the wheel.

Trouble with SOAP Web Service

I am trying to use a SOAP Web Service provided by a third party. I am having trouble getting the service to work correctly in .NET 3.5. I have added it as a web reference and all seems to go well. Problem is when I call the service all I get returned is a NULL object. I have worked with the provider and there service appears to be working correctly. He did mention:
"We are using Axis2 Document/Literal and support SOAP 1 and 2."
I am not exactly sure what that means as I am a semi-newbie to using Web Services. Do I need to change some configuration parameters or something in .NET to get this service to work correctly?
From my experience, web service interoperability isn't the magic it claims to be. Especially, between .NET and Java.
Axis2 is a Java web service "engine"
Document/Literal is a style of writing a WSDL that results in a special SOAP appearance
SOAP 1 and 2 (you probably know) the message format and specific versions thereof
all I get returned is a NULL object
Is not much to start with, could you provide more information?
I would recommend, that you try to intercept the exchanged SOAP messages (you can use tcpmon) and check if they are valid. You would probably get an exception if the remote service can't handle your request so I guess your client as some trouble parsing the response. Additionally, you can use soapUI to generate example request to see what a valid request should look like.
Doc/lit (and at least SOAP 1) ought to work with WCF, but I'm not sure how the legacy (pre-.NET 3.0) web service client deals with that.
Did you, in Visual Studio, add a web reference or a service reference? If you added a web reference, you are not using WCF, which may be the reason it's not working. If this is the case, you should delete the web reference and see if adding a service reference instead helps.
It sounds like the proxy that you have generated (via add web reference) is not de-serializing the xml into the type you expect.
As wierob suggests the first thing I would do is trace the messages that you send to the service and the response you receive - that way you can examine the xml you can check that the proxy is creating a suitable request message and see whether the response does contain data that is not being de-serialized into the object you expect
As well as tcpmon you could use fiddler (from microsoft) to trace the traffic or the simplest would be to switch on the message tracing in WCF to log the request and response to files which could then you examined in the service trace viewer tool
With these kind of interoperability issues I find the best thing is to look at the message "on the wire" first - you may then have to tweak the wsdl so that the proxy gets generated correctly or hand craft the proxy yourself
If you post the wsdl and your proxy that might give us a clue as to the issues

How to see SOAP data my client application sends?

I have a project where I have created web service proxy classes with wsdl.exe and then simply create an instance of that class (inherits System.Web.Services.Protocols.SoapHttpClientProtocol) and call the method that should send a SOAP message. I'm using Visual Studio 2008 if that matters. And I'm trying this in my development machine without access to actual web service that is located inside of customer's intranet. So, the sending will of course not succeed and I will not get any response back but all I would like to see is the exact content of SOAP messages this solution creates and tries to send. How do I see that?
Use fiddler.
Have a look at SOAPUI from eviware.com.
Its a free for personal use Java app. Among other things you can
set it up to run as a dummy test server. Just load up hte WSDL
and enter the dummy data.
In test server mode it will log your requests so you can see whats happening
inside the request message.
If you're Web service is accessed by clear text, non-SSL HTTP, you can just use a sniffer, like Wireshark, to see the data coming from and to your application. Wireshark can trace, filter and analyze wire data. I have used it do debug HTTP and other protocols many times, and it's a great tool to do this.
SOAP messages are simply XML data sent using the HTTP POST method. So you can for example install a local web server on your development machine, configure your web service to use some dummy URI on this server, and grab the network traffic with WireShark (AKA ethereal). The big advantage of this method is that it involves no coding.
Alternatively you can use an HTTP echo server that dumps its incoming traffic, like this one (found while googling "http echo server"):
You can intercept the call with tcpMon

Categories