У меня проблема с вызовом веб-службы C # из Windows-программы VB6, и я надеюсь на некоторую помощь.
Проблема в том, что request.stream, который читает веб-служба, пуст и поэтому возвращаети ошибка в том, что корневой узел отсутствует.
Код VB6, который вызывает службу:
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
Код веб-службы:
[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 <websales@another.co.uk>", "benjamin@another.co.uk", "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 <websales@another.co.uk>", "benjamin@another.co.uk", "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;
}
}
}
У меня есть тестовый код C #, который вызывает веб-сервис и работает нормально:
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);
}
}
Любая помощь в том, как заставить веб-сервис читать тело / поток http-запроса из вызова VB, будет полезна.