Reputation: 1376
I have an issue calling a C# web service from a VB6 windows program and I'm hoping for some help.
The issue is that the request.stream that the web service reads is blank and therefore returns and error that the root node is not present.
The VB6 code that calls the service is:
Private Sub CmdHTTPPost_Click()
Dim http As WinHttp.WinHttpRequest
Dim strURL As String, strFormData As String
Dim pvtPartNo As String
Text1.Text = ""
strFormData = TxtVoucherNo.Text
strURL = "http://proof.another.co.uk/admin/stockupdate.asmx"
http = New WinHttp.WinHttpRequest
' Open an HTTP connection.
http.SetTimeouts(20 * 1000, 20 * 1000, 20 * 1000, 20 * 1000)
http.Open("POST", strURL, False)
http.SetRequestHeader("Content-Type", "text/xml; charset=uft-8")
http.ResponseStream()
http.Send(strFormData)
http.WaitForResponse()
Text1.Text = http.ResponseText
http = Nothing
End Sub
Private Sub Form_Load()
TxtVoucherNo.Text = TestWebPost()
End Sub
Public Function createHeaderXML(pvtBranchNo As String, pvtRef As String) As String
createHeaderXML = "<?xml version =" & """" & "1.0" & """" & " ?>" & _
"<soap:Envelope xmlns:xsi=" & """" & "http://www.w3.org/2001/XMLSchema-instance" & """" & " xmlns:xsd=" & """" & "http://www.w3.org/2001/XMLSchema" & """" & " xmlns:soap=" & """" & "http://schemas.xmlsoap.org/soap/envelope/" & """" & ">" & _
"<soap:Body>" & _
"<UpdateStock xmlns=" & """" & "http://www.another.co.uk.admin.stockupdate/" & """" & "/>" & _
"<txn>" & _
"<branch>" & pvtBranchNo & "</branch>" & _
"<receipt>" & pvtRef & "</receipt>"
'"<txn xmlns:soap=" & """" & "http://schemas.xmlsoap.org/soap/envelope/" & """" & " xmlns:xsi=" & """" & "http://www.w3.org/2001/XMLSchema-instance" & """" & " xmlns:xsd=" & """" & "http://www.w3.org/2001/XMLSchema" & """>" & _
'"<!--! " & Format(Now, "yyyy-mm-dd hh:nn:ss") & " -->" & _
'"<soap:Envelope xmlns:xsi=" & """" & "http://www.w3.org/2001/XMLSchema-instance" & """" & " xmlns:xsd=" & """" & "http://www.w3.org/2001/XMLSchema" & """" & " xmlns:soap=" & """" & "http://schemas.xmlsoap.org/soap/envelope/" & """" & ">" & _
'"<soap:Body>" & _
'"<UpdateStock xmlns=" & """" & "http://www.another.co.uk.admin.stockupdate/" & """" & "/>"
End Function
Public Function createEndXML()
createEndXML = "</txn>" & _
"</soap:Body>" & _
"</soap:Envelope>"
End Function
Public Function createPartXML(pvtPartNo As String, pvtStatus As String, pvtQuantity As String) As String
createPartXML = "<orderline>" & _
"<partno>" & pvtPartNo & "</partno>" & _
"<quantity>" & pvtQuantity & "</quantity>" & _
"<condition>" & pvtStatus & "</condition>" & _
"</orderline>"
End Function
Public Function TestWebPost() As String
Dim testString As String
testString = createHeaderXML("1", "111554") + createPartXML("xt801", "1", "2") + createPartXML("xt1200", "1", "1") + createEndXML()
TestWebPost = testString
End Function
The web service code is this:
[WebService(Namespace = "http://www.another.co.uk.admin.stockupdate/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class stockupdate : System.Web.Services.WebService
{
[WebMethod]
public string UpdateStock()
{
Boolean complete = false;
int errorPlace = 0;
string strmContents = "";
XmlNode txn = null;
string postMessage = "";
try
{
ArrayList orderlines = new ArrayList();
int branch = 0;
Int64 receipt = 0;
errorPlace++; // = 1
using (System.IO.StreamReader reader = new System.IO.StreamReader(HttpContext.Current.Request.InputStream))
{
while (reader.Peek() >= 0)
{
strmContents += reader.ReadLine();
}
}
// set testing content for xml..
// strmContents = "<?xml version =\"1.0\" ?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><UpdateStock xmlns=\"http://www.another.co.uk.admin.stockupdate/\"/><txn><branch>1</branch><receipt>111554</receipt><orderline><partno>xt801</partno><quantity>2</quantity><condition>1</condition></orderline><orderline><partno>xt1200</partno><quantity>1</quantity><condition>1</condition></orderline></txn></soap:Body></soap:Envelope>";
postMessage += strmContents;
errorPlace++; // = 2
XmlDocument thisXmlDoc = new XmlDocument();
thisXmlDoc.LoadXml(strmContents);
XmlNamespaceManager nsmanager = new XmlNamespaceManager(thisXmlDoc.NameTable);
nsmanager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
//txn = thisXmlDoc.DocumentElement;
errorPlace++; // = 3
// Get Branch
XmlNode bchNode = thisXmlDoc.SelectSingleNode("/soap:Envelope/soap:Body/txn/branch", nsmanager);
branch = Convert.ToInt32(bchNode.InnerText);
errorPlace++; // = 4
XmlNode rcptNode = thisXmlDoc.SelectSingleNode("/soap:Envelope/soap:Body/txn/receipt", nsmanager);
receipt = Convert.ToInt32(rcptNode.InnerText);
errorPlace++; // = 5
//get Companies
XmlNodeList olItems = thisXmlDoc.GetElementsByTagName("orderline");
foreach (XmlNode orderline in olItems)
{
try
{
XmlNode partNo = orderline.SelectSingleNode("partno");
XmlNode quantity = orderline.SelectSingleNode("quantity");
XmlNode condition = orderline.SelectSingleNode("condition");
string[] item = new string[3] { partNo.InnerText, quantity.InnerText, condition.InnerText };
orderlines.Add(item);
}
catch (Exception ex)
{
postMessage = ex.Message;
}
}
errorPlace++; // = 6
string strItems = "";
string strQuantities = "";
try
{
// Update stock numbers
foreach (string[] orderItem in orderlines)
{
string sql = "";
// Get stockitem_id
using (SqlConnection stockConn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString))
{
errorPlace++; // = 7
stockConn.Open();
sql = "SELECT stockitem_id FROM tbl_stockitem WHERE stockitem_number LIKE '" + orderItem[0] + "'";
SqlCommand idCommand = new SqlCommand(sql, stockConn);
int thisStockitemId = Convert.ToInt32(idCommand.ExecuteScalar());
if (thisStockitemId > 0)
{
if (Convert.ToInt16(orderItem[2]) == 1)
{
sql = "UPDATE tbl_storestockitemxref SET stockitem_numbernew = stockitem_numbernew - " + orderItem[1] + " WHERE stockitem_id = " + thisStockitemId + " AND store_id = " + branch;
}
else
{
sql = "UPDATE tbl_storestockitemxref SET stockitem_numberused = stockitem_numberused - " + orderItem[1] + " WHERE stockitem_id = " + thisStockitemId + " AND store_id = " + branch;
}
SqlCommand updateCommand = new SqlCommand(sql, stockConn);
updateCommand.ExecuteNonQuery();
if (!strItems.Equals(""))
{
strItems += "|" + orderItem[0];
}
else
{
strItems += orderItem[0];
}
if (!strQuantities.Equals(""))
{
strQuantities += "|" + orderItem[1];
}
else
{
strQuantities += orderItem[1];
}
}
else
{
Exception ex = new Exception("Couldn't find part number " + orderItem[0] + "; ");
throw ex;
}
}
}
}
catch (Exception ex)
{
postMessage += ex.Message;
}
// Register complete on receipt table
try
{
errorPlace++; // = 8
using (SqlConnection receiptConn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString))
{
receiptConn.Open();
string sql = "INSERT INTO tbl_livestockreceipts (receipt_no, receipt_branch, receipt_message, receipt_items, receipt_quantities) VALUES (" + receipt + ", " + branch + ", '" + postMessage + "', '" + strItems + "', '" + strQuantities + "')";
SqlCommand receiptCommand = new SqlCommand(sql, receiptConn);
receiptCommand.ExecuteNonQuery();
}
complete = true;
}
catch (Exception ex)
{
postMessage += ex.Message;
// do nothing
anotherDAL.emails emailFuncs = new anotherDAL.emails();
string emailMsg;
emailMsg = "<p>Error on the INSERT RECEIPT function for live updates</p>";
emailMsg += "<p>" + ex.Message + "</p>";
emailFuncs.sendEmail("another <[email protected]>", "[email protected]", "Live stock update error!", "Oh, Bugger!", "", "<br/><br/>" + emailMsg + "<br/><br/>");
complete = false;
}
}
catch (Exception ex)
{
postMessage += ex.Message;
// do nothing
anotherDAL.emails emailFuncs = new anotherDAL.emails();
string emailMsg;
emailMsg = "<p>Error on function for live updates</p>";
emailMsg += "<p>" + ex.Message + "</p>";
emailFuncs.sendEmail("another <[email protected]>", "[email protected]", "Live stock update error!", "Oh, Bugger!", "", "<br/><br/>" + emailMsg + "<br/><br/>");
complete = false;
}
if (complete)
{
return "Success" + "; error = " + errorPlace.ToString() + "<br /><br />" + postMessage + "<br /><br />Input: " + strmContents;
}
else
{
return "Fail" + "; error = " + errorPlace.ToString() + "<br /><br />" + postMessage + "<br /><br />Input: " + strmContents;
}
}
}
I have a test C# code that calls the web service and works fine:
protected void StockUpdateService(object sender, EventArgs e)
{
try
{
Uri address = new Uri("http://proof.another.co.uk/admin/stockupdate.asmx/UpdateStock"); //Uri address = new Uri("http://localhost:300/admin/stockupdate.asmx/UpdateStock"); //
// Create the web request
HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
// Set type to POST
request.Method = "POST";
request.ContentType = "text/xml; charset=utf-8";
// Set content of request
// string xmlRequest = "<?xml version=\"1.0\" ?><txn><branch>1</branch><receipt>111554</receipt><orderline><partno>xt801</partno><quantity>2</quantity><condition>1</condition></orderline><orderline><partno>xt1200</partno><quantity>1</quantity><condition>1</condition></orderline></txn>";
// string xmlRequest = "<?xml version =\"1.0\" ?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><UpdateStock xmlns=\"http://www.another.co.uk.admin.stockupdate/\"/><txn><branch>1</branch><receipt>111554</receipt><orderline><partno>xt801</partno><quantity>2</quantity><condition>1</condition></orderline><orderline><partno>xt1200</partno><quantity>1</quantity><condition>1</condition></orderline></txn></soap:Body></soap:Envelope>";
string xmlRequest = "Blah";
StringBuilder data = new StringBuilder();
data.Append(xmlRequest);
// Create a byte array of the data we want to send
byte[] byteData = UTF8Encoding.UTF8.GetBytes(data.ToString());
// Set the content length in the request headers
request.ContentLength = byteData.Length;
// Write data
using (Stream postStream = request.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
}
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Console application output
Response.Write(reader.ReadToEnd());
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
Any help as to how to get the web service to read the http request body/stream from the VB call would be helpful.
Upvotes: 1
Views: 1468
Reputation: 10855
You have a typo in the VB6 code:
charset=uft-8
vs
charset=utf-8
EDIT1:
Aren't you asking for a response stream before you send your POST content
http.ResponseStream()
http.Send(strFormData)
Try inverting these so you send first
Upvotes: 2