Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SOS! CALLING FOR HELP TO SEND XML THROUGH WEB 2

Status
Not open for further replies.

JenniReyniss

Programmer
Mar 23, 2010
12
IS
Hi everybody

I'm using WebService created in .NET and I'm calling it with VFP9.
There are two methods that I'm gonna use.
One to receive data and one to send data.
The one that I'm receive data works fine but when I try to send I got some problem.

When I look at the method in VFP (in the XML Web Services part) it says that the syntax for it is :
(Parameter names and such have been changed.)
Code:
SendXML(User AS string, UserPwd AS string, service AS string, receiver AS string, xml AS XMLDOMNodeList, UserMessage AS string) AS VOID
The information I got from the company that I'm trying to send to is that the code for the XML should be something like this (presumably with .NET in mind) :
Code:
<coolio_words xmlns="[URL unfurl="true"]http://www.company.com/schemas/inc/coolie/1"[/URL] message="string_1" sender="sring_2" system="strng_3">
   <customer_insert staff="string_4" ktl="string_5" reject="" batch="string_6" country="string_7">
      <customer cost="string_8" date="2001-01-01T00:00:00" costSystem="string_9" costName="string_10" />
   </customer_insert>
</coolio_words>
I have tried to find the solution for my problem and the closest thing I found is :

I create a form, put a button on it an in the click I drag the WebService in it from the toolbox.
In the code that comes automatically I put after the '* Call your XML Web service here.' this code here :
Code:
TEXT TO lcXML TEXTMERGE NOSHOW PRETEXT 7
   <coolio_words xmlns="[URL unfurl="true"]http://www.company.com/schemas/inc/coolie/1"[/URL] message_id="string_1" senderId="sring_2" systemId="strng_3">
      <customer_insert staffId="string_4" ktl="string_5" rejectReason="" batchID="string_6" countryCode="string_7">
         <customer cost="string_8" date="2001-01-01T00:00:00" costSystem="string_9" costName="string_10" />
      </customer_insert>
   </coolio_words>
ENDTEXT

leSend = loWebSevice.SendXML("something_1","something_2","something_3","something_4",lcXML,"something_5")
When I try this I get this error :

Error: 1429 - OLE IDispathc exception code 0 from Client: Client:Incorrect number of parameters supplied for SOAP request HRESULT=0x80070057: The parameter is incorrect.
- Clinet:Unspecified client error. HRESULT=0x80070057: The parameter is incorrect.
..
Client:Incorrect number of parameters supplied for SOAP request HRESULT=0x80070057: The parameter is incorrect.
- Clinet:Unspecified client error. HRESULT=0x80070057: The parameter is incorrect.


What am I missing or doing wrong?

After searching for solution and seeing some codes I consider if my problem is :
(despite of my lack off knowledge)
- should I use '< ?xml version = "1.0" ....' and then how?
- shouldn't I use 'TEXTMERGE' to send in XML (XMLDOMNodeList). And than what is the best / right way to do it?
- something about schema. Is it not identified or wrongly?
- something to do with 'diffgram'. Should I use it and than how?
- is there something missing or not identified?
- is the date making the error?

Please help me and if you need more information please let me know.
All help would be appraised.

With hope that this is just a missing '( )' problem or something simple as that.

With thanks in advance,
JensReyniss
 
Mike,
By the way, is it safe to assume that all users will have .NET installed? It could be quite a big overhead to add to a VFP app's setup routine.

Yes and no. Install Shield adds .net framework libraries as a "download if not already installed" option. At this time it is almost impossible to find a windows computer w/o .Net installed. You can say that it is installed on all windows computers that did their updates. Many windows components themselves are based on those runtimes it is fair to think it is already installed (some get it asupdates, some already have it as part of default installation - ie: vista, windows 7 ... installs it). Unsafe part might be which version your code targets. For example in the sample I will show the target is .Net framework 4. It is not released yet but would be on April 14th (if release date haven't changed since last change I heard:) I could have done it shorter and yet compatible with .Net 3.5 which has been released long ago but I preferred 4 just because of added support of "Contains" in Linq to EF query (as a strong believer of Linq and EF - future of data centric applications IMHO).

OK I think doing the sample in another post would be more appropriate.





Cetin Basoz
MS Foxpro MVP, MCP
 
Since the web service in question wasn't given and no idea on WSDL instead of doing this for a web service I did as a call to another private method in .Net class. If we knew the web service address and have a chance to use for testing the difference would be just invoking a wizard, point to asmx or wsdl address and let Visual Studio create the proxy class.

-Step 1: Created a new C# class library project
-Step 2: In project properties:

Build tab set the platform target to x86 (this is important - VFP wouldn't be able to talk to 64 bits compilations and unless target is limited .Net dll would use 64 bits on 64 bits OS). Also mark "Register for COM interop".

On Signing tab mark "sign the assembly" and give a key filename (I gave "cetinbasoz.snk" as a sample).

On clients you would use this snk file + dll and regasm for registering. .Net also is very successful in creating deployment packages.

-Step 3: Added a ADO.Net entity model to project and using wizard generated the model from Northwind database named "NorthwindEntities".

In code I also explicitly point it to my:
.\SQL2008 instance.

You can see how this is done in my blog at:

(It is a very simple process using the designer, just add a connection to SQL Server instance, mark the tables -views and SPs as well if you like- you want in your model and VS do the rest. Really easier than adding RV or CA IMHO)

-Step 4: Wrote the main code and built.

Here is the code (I will give more details in next post):

Code:
using System;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Xml;
using System.Xml.Linq;
using System.IO;
using System.Data.EntityClient;
using System.Data.SqlClient;

namespace VFPBridgeSample
{
    [ProgId("SampleNetBridge.VFP")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class VFPBridge
    {
        public string TestWithPreCodedValues()
        {
            // SampleRequest Expects an XML likSampleNetBridge.VFPSampleNetBridge.VFPSampleNetBridge.VFPe:
            string idList = @"
            		<IDList>
            			<customerID>BONAP</customerID>	
            			<customerID>ANATR</customerID>
            			<customerID>CENTC</customerID>
            		</IDList>";
            return SampleRequest(idList);
        }

        public string SampleRequest(string idListXML)
        {

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(idListXML);

            XmlNodeList customerIDNodes = doc.GetElementsByTagName("customerID");

            StringBuilder sb = new StringBuilder();
            StringWriter w = new StringWriter(sb);
            GetCustomerInfo(customerIDNodes).Save(w);
            return sb.ToString();
        }

        #region Db Connection
        private EntityConnection GetConnection()
        {
            SqlConnectionStringBuilder sqlBuilder =
                new SqlConnectionStringBuilder();

            EntityConnectionStringBuilder entityBuilder =
                new EntityConnectionStringBuilder();

            sqlBuilder.DataSource = @".\SQL2008";
            sqlBuilder.InitialCatalog = "Northwind";
            sqlBuilder.IntegratedSecurity = true;

            entityBuilder.Provider = "System.Data.SqlClient";
            entityBuilder.ProviderConnectionString = sqlBuilder.ToString();

            // Set the Metadata location.
            entityBuilder.Metadata = @"res://*/NWModel.csdl|res://*/NWModel.ssdl|res://*/NWModel.msl";

            return new EntityConnection(entityBuilder.ToString());
        }
        #endregion

        private XElement GetCustomerInfo(XmlNodeList customerNodes)
        {
            string[] customerIDList = new string[customerNodes.Count];
            for (int i = 0; i < customerNodes.Count; i++)
            {
                customerIDList[i] = customerNodes[i].InnerText;
            }

            NorthwindEntities db = new NorthwindEntities(GetConnection());
            foreach (string customerId in customerIDList)
            {

            }
            var orders = (from o in db.Orders
                             .Include("Customer")
                             .Include("Order_Details")
                             .Include("Employee")
                             .Include("Shipper")
                             .Where(o => customerIDList.Contains(o.Customer.CustomerID))
                          orderby o.OrderDate descending
                          select o).ToList();

            XElement xmlOrders =
                new XElement("orders",
                  from o in orders
                  orderby o.OrderDate descending
                  select
                      new XElement("order",
                        new XAttribute("CustomerID", o.Customer.CustomerID),
                          new XAttribute("id", o.OrderID),
                          new XAttribute("OrderedOn", o.OrderDate),
                          new XAttribute("OrderAmount", o.Order_Details.Sum(od => od.Quantity * od.UnitPrice)),
                          new XAttribute("IsShipped", o.ShippedDate != null),
                          new XAttribute("shipped", o.ShippedDate ?? DateTime.MaxValue),
                          new XAttribute("SalesMan", o.Employee.FirstName + " " + o.Employee.LastName),
                          new XAttribute("SalesmanID", o.Employee.EmployeeID),
                          new XAttribute("Carrier", o.Shipper.CompanyName)
                          ));

            return xmlOrders;
        }
    }
}


Cetin Basoz
MS Foxpro MVP, MCP
 
I just thought this might have been a blog entry in my blog:) Haven't updated it for a long time.

OK assuming you build the DLL in VS. Here is the sample VFP code:

Code:
SYS(2339,1)
LOCAL oBridge as 'SampleNetBridge.VFP'
oBridge = CREATEOBJECT('SampleNetBridge.VFP')

lcResult = oBridge.TestWithPreCodedValues()
XMLTOCURSOR(m.lcResult, 'MyCursor')
BROWSE

TEXT TO lcXmlIDList noshow
<IDList>
	<customerID>ALFKI</customerID>	
	<customerID>BONAP</customerID>
	<customerID>CENTC</customerID>
	<customerID>CENTC</customerID>
</IDList>
ENDTEXT

lcResult = oBridge.SampleRequest(m.lcXmlIDList)
XMLTOCURSOR(m.lcResult, 'MyCursor')
BROWSE

What I find cool about this process is that writing both the .Net and VFP parts myself and knowing what I need I can create "bridges" and "utilities" etc quickly with the parameter types I want. For example I don't struggle trying to pass or resolve a .Net dataset. Instead I pass and return what I find the simplest for a task.

BTW COM interop is cool and works quite well. You can find all the details about "how-to" in "All-In-One Code Framework
" located at:


It is a framework that gets updated often and you can find answers to how-to tasks.

And also you can find a simple COM Interop sample here using F# (getting Fibonacci numbers):


The site language is in Turkish but code talks:) Directly go to 3rd message in that thread and you would see 3 parts:
-The F# code
-Registering using command prompt
-VFP call

it is quite short! Creating Olepublic DLL in VFP is not easier:)


Cetin Basoz
MS Foxpro MVP, MCP
 
Ahh, I see I forgot to remove a redundant foreach() loop that does nothing. It was there initially to write a .Net 3.5 compatible version.

Cetin Basoz
MS Foxpro MVP, MCP
 
I just want to let you know how this problem of mine is going and I want to start by thanking you all, who commented, for your help.

What I did was I replaced this text :
Code:
loWSHandler = NEWOBJECT("WSHandler",IIF(VERSION(2)=0,"",HOME()+"FFC\")+"_ws3client.vcx")
loGatewayService = loWSHandler.SetupClient("[URL unfurl="true"]http://....SomeWebService....[/URL]

with this text :
Code:
loGatewayService = CREATEOBJECT("MSSOAP.SoapClient30")
loGatewayService.MsSoapInit("[URL unfurl="true"]http://....SomeWebService....[/URL]

like it is suggested in this thread :

and I added this before calling the web service :
Code:
loDOM = Createobject("MSXML.DomDocument")
loDOM.LoadXML(lcXML)


After this I can send through the web service but the error still pops up.
So I just took out the error messagebox so it won't pop up.
The error is still there but it have no effect.

I'm posting this with hope that this will help somebody in the future.

Respect,
Jens
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top