views:

216

answers:

5

Okay this is a real headscratcher.

I have an application which calls a web service. It is a valid web service that pulls some data from a SQL server db, whacks it into an XML document and returns it to the Winforms app for processing.

This works fine in debug.

It fails when you run it normally but it does so returning specific data that is supposed to signal there are no valid records returned from the DB with a certain ID.

If you switch on a Wireshark packet capture after it has failed once in the release version it then works fine again.

If you start the packet capture before you get to the page that requests the service then it errors in the same way as it does when you are running it normally.

The packet capture of the one that produces the correct result shows the application make the request and then receive the data it's expecting.

The packet capture of the one that errors shows the application make the request and then explicitly receive the "no records returned" error.

One thing we have noted is that it takes about 0.25/0.5 seconds to work when it works but when it doesn't work it responds much faster.

EDIT: Okay, I knew I forgot something. I was convinced, initially, that it was the service itself. Or the SQL. So I tested the SQL, no issues. I debugged the service locally. No issue. I built a test harness to feed data into the service from my browser and capture the reult to a label. I fed it some data. It was fine. It's not the service. The service is okay. Except, apparently, when called through my Winforms app, which the packet capture confirms is sending the correct data up. And then it only fails under certain conditions. sigh

Does anyone have any idea why this might be?

+2  A: 

It could be an issue with your web method itself. See how it connects/disconnects to the database. See if you can mock the results without calling the database - build the results by hand and call the web service. Also create a unit test that calls your web method straight, without using a web service call and check its behavior.

Otávio Décio
Sorry, no cigar. See my edit. Good prompt for my memory though. Thanks.
A: 

Double check that your winforms app isn't being blocked by the FW.

Darryl Braaten
Unfortunately same problem occurs at two sites. And only intermittently.
Have you tried running the requests through a proxy like tcpTrace instead of Wireshark?
Darryl Braaten
See my update answer.
A: 

Update: I started monitoring through WebScarab from OWasp and after a "failed" request I used the applications manual request plugin to copy the raw request and send it via the Scarab direct.

This "failed" job then worked perfectly, a couple of times.

So what the winforms app is sending is valid. Is there some comms setting in Web Service requests that I am missing?

A: 

I've run into similar issues in the past. I ended up having to wrap the GetWebRequest method and adjust the parameters.

namespace [NameSpaceHere]
{
    public partial class [the name of the proxy class created by Visual Studio]
    {
        protected override System.Net.WebRequest GetWebRequest(Uri uri)
        {
            System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)base.GetWebRequest(uri);

            // turning this off can cause authentication errors
            //            webRequest.KeepAlive = false;

            webRequest.ProtocolVersion = HttpVersion.Version10;
            webRequest.ServicePoint.Expect100Continue = false;
            return webRequest;
        }
    }
}
Brad Bruce
Exciting news. I shall experiment with this and see what happens.
+1  A: 

In a masterstroke of misdirection the answer to this problem resolved due to things other than those mentioned here. Excellent suggestions nonetheless.

In this case it turned out that the problem we were having was with how our system defines the completion of a credit card charge. The system is supposed to wait for the successful authorisation of a charge and it's "Post Authorisation" process to consider the charge a "success".

The exact reason for this is due to the unusual nature of our product and the stages of a given banking transaction. For online payments in the UK a charge is not able to be "Post Authorised" until the goods have "shipped".

If we sold books (or mugs, or novelty garden gnomes) then notification of successful Pre Auth would be enough to consider the transaction complete as shipping would take place a bit later. We sell concert tickets, more precisely we sell entry to gigs the physical representation of which is the ticket. The minute we have the customer's money they are, effectively, guaranteed their entry to the gig under all normal cricumstances.

In a real sense our product ships the second the transaction is complete, thus a pre-auth and post-auth process need to complete to count the transaction as "successful".

However, when the pre-auth completes successfully the customer is assured it will post auth too so we show them the "complete" screen at this moment to make the app run faster. On the box office that asks for ticket prints this is the same. However, what nobody knows is that the post auth may take a further minute to three minutes to post auth and thus be a complete "success". If the charge is not a success it will not be returned from the printing service because the underlying DB query returns its "no orders match" result, so all I had to do, in the end, was wait until it had finished post authing and it worked fine.

So all in all a bit of a storm in a teacup. Now we just need the underlying SQL to return the order at the same time as the success page but not include failed charges (such as might result by miskeying fraud detection fields such as cardholder postcode) along with the successful charge we want to print details of.

Thanks fo everyone's help. Sorry it was a relatively mundane fix.

I like the "store in a teacup" - haven't heard that one before. +1 for the detailed description of solution.
Gavin Miller