I have several methods implemented in a webservice written in C#. The
methods execute SQL against a SQL Server 2005 db and returns a Dataset (as
XML). I am utilizing the webservice from a VC++ app by adding the web ref to
the project which creates the header file for making the calls. I traced
through the method call in my app and found the problem in the
CAtlHttpClientT<TSocketClasstemplate implementation. The problem is
happening in the Navigate method:
CAtlHttpClientT<TSocketClass>::Navigate
this calls the function: ReadHTTPResponse which calls:
CrackResponseHeader which calls ParseStatusLine() (all methods in
CAtlHttpClientT<TSocketClass>)
ParseStatusLine works its way through the HTML header buffer until it
reaches a space which is followed by the status code. The Status Code
appears to be 200 which is documented as a valid code. However, the code
that follows is:
if (*pBuffer >= '0' && *pBuffer <= '9')
{
// probably a good status code
m_nStatus = strtol((LPSTR)pBuffer, (LPSTR*)&pEnd, 10);
if (Checked::get_errno() == ERANGE)
return NULL; // bad status code
}
--------------------------------------------------------------------
This is the contents of pBuffer:
200 OK
Server: Microsoft-IIS/5.1
Date: Tue, 12 Dec 2006 05:26:26 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 6968
--------------------------------------------------------------------
In the debugger, m_nStatus = 200. The Checked::get_errno() returns 34 which
apparently is in ERANGE because it resolves to TRUE and returns NULL which
tells the caller that the header parse failed (Returns the code:
RR_PARSEHEADERS_FAILED).
When I run the debugger on the webserver size, it appears that the SQL
executes properly and the resulting XML looks OK. the strange thing is I
have another call to the webservice from this app and it works fine. Both
webservice methods return a Dataset (as XML). The only difference is the
working method has no params and the problem method has 4 params.
This is the implementation of the method in the web service that is failing
when I call it:
--------------------------------------------------------------------
public DataSet GetTimeListByDateRange(string startDate, string endDate,
string sEventType, int StaffID, int
ResidentID)
{
SqlConnection conn;
SqlDataAdapter dataAdapter;
DataSet timeDataSet;
string cmdString;
cmdString = "SELECT * FROM Time";
conn = new SqlConnection("Server
=localhost;uid=aUser;pwd=myPW;database=myDB");
dataAdapter = new SqlDataAdapter(cmdString, conn);
timeDataSet = new DataSet();
dataAdapter.Fill(timeDataSet);
string theXML = timeDataSet.GetXml(); // used to debug the XML
return timeDataSet;
}
--------------------------------------------------------------------
This is how I call it from my VC++ code:
MyDataService::CMyDataService DataServer;
CString strStartTime = startDate.Format(_T("%m/%d/%Y"));
CString strEndTime = endDate.Format(_T("%m/%d/%Y"));
BSTR bstrEventType = strEventType.AllocSysString();
BSTR bstrStartTime = strStartTime.AllocSysString();
BSTR bstrEndTime = strEndTime.AllocSysString();
BSTR bstrResults;
HRESULT hr = DataServer.GetTimeListByDateRange(bstrStartTime, bstrEndTime,
bstrEventType, 0, 0, &bstrResults);
// HR is return E_FAIL because of the NULL returned as explained above
// bstrResults is a bad pointer
--------------------------------------------------------------------
I can't figure out why one works and the other doesn't (although I have
gotten the good one to fail once in a while).
Rob C