I have a small application written in c# consuming a webservice which returns a list of companies. I would like to use the same in PB in order to integrate the web service consumption with my business requirements. The only problem that I have faced is how to add the message header.
One of the issues with PowerBuilder Native's support for web services is that it is based on ASP.Net Web Services. That technology, introduced with.Net 1.0, doesn't provide support for anything other than simple XML over HTTP SOAP services. Microsoft introduced WCF web services in.Net 3.0 to provide support for a much creater variety of SOAP services. In particular, WCF web services:. Can be accessed through protocols other than HTTP, such as TCP or named pipes. Added support for web services standards such as WS-Security, WS-Addressing, WS-ReliableMessaging, WS-Coordination and WS-AtomicTransaction.
For this example, we're going to use the Amazon Web Services Product Advertising API as the more complicated web service that we can't access directly from PowerBuilder Native. That's largely because Amazon requires custom headers - including signing of the request. That's the same example that I used in that article from 2012. We're going to use very similar code, so I won't explain what all of it does. You can refer back to the 2012 article for that explanation. What I will explain though are the differences between the code we're going to use for this example and the code from 2012.
The problem isn't with PowerBuilder. It's actually with the Amazon Web Services. The bug that was filed on the problem back in 2011, and it also discusses the solution.
I'm not quite sure why Amazon hasn't fixed it yet. The problem is that what Amazon says it's going to return int the WSDL for the ImageSets property of an Item and what it actually does return are two different things. Perhaps Java or other web service clients handle that gracefully, but C# doesn't. If you create a proxy directly off Amazon's WSDL and call the ItemSearch method, what you'll get is a.Net exception of.
Now reference that file on your workstation rather than the original Amazon WSDL in the web service client proxy wizard. Once you've created the proxy project, run it to create the WCF client. The project will end up generating something like 11 different non-visual user objects. That's because the Amazon WSDL contains 11 different service binding, one for each of the country websites ( CA, CN, DE, ES, FR, IN, IT, JP, UK and US ).
There is also a default one set to US. If you're in the US, keep the first one and delete the rest. If you're in a different country use the one that is for your country and delete the others.Figure 6 - Amazon Web Service Bindings. I defined them all as strings because that's the data type that Amazon uses to return them. Note that I'm using a non-visual object rather than a structure here.
That's because for purposes of returning data from a web service, non-visual object handle representations of nulls better than structures do.Now go back to the non-visual object that was created by the WCF Service wizard. We want to create a function on that object that uses the WCF client to talk to Amazon and then returns the data to PowerBuilder Native.
I've called the method ofsearch. For this example, I'm not passing any arguments. For the return, I've indicated that it will return an array of the nitem non-visual object I just defined.
(One nice feature of PowerBuilder.Net is that is does support returning arrays from functions).Now for some code. You'll need to adjust the following based on what namespace you used for your WCF proxy and WCF service. I used 'wcfclient' for the client and 'TeamSybase' for the service. I also renamed the non visual object created by the WCF client project to just 'awsecommerceservice'. The original name generated by the WCF client project was quite long.
client.wcfConnectionObject.BasicHttpBinding.MaxReceivedMessageSize = 1000000As will be noted a bit later, I changed the for the request form 'Small' (2012) to 'Medium' (today). That's because in 2012 I was just returning titles and today I want more information ( authors, publisher, publication date, etc) that required getting more data back in the service response. So much data in fact, that it exceeds the default size that WCF allows for the size of the message (65,536 bytes). I've increased the size significantly to allow for the additional data.
Do while itemenum.MoveNextitem = itemenum.Currentitemsindex = create TeamSybase.nitemitemsindex.Title = item.ItemAttributes.Titleitemsindex.Author = item.ItemAttributes.Author1itemsindex.Publisher = item.ItemAttributes.Publisheritemsindex.ISBN = item.ItemAttributes.ISBNitemsindex.PublicationDate = item.ItemAttributes.PublicationDateif not IsNull ( item.ItemAttributes.ListPrice ) thenitemsindex.Price = item.ItemAttributes.ListPrice.FormattedPriceend ifindex = index + 1loop. Once again I'm returning more data in this example than I did in 2012, so we're using a type to collect the data and accessing more attributes. Because I'm trying to keep this simple, I'm only pulling the first author for a book if there are multiple authors.Now that we've defined the method for our web service we need to go back to the web service project object that was created by the wizard. When the wizard was first run, there were no methods on the non-visual object and so there was nothing to expose in the service. Now we have a method to expose.Figure 10 - WCF Service Options.
So we need to check the checkbox in front of our new method so the project knows what to expose. I've also give the service an alias of 'Search' that is a bit more web service friendly than 'ofsearch'. I should probably also alias the web service name as well, but haven't done so for this example.
Nor have I changed the target namespace, which you should do for a production web service.There's a few other things I've customized here, and you'll need to do the same. I'll explain what each of them is. Note for changes to the service attributes (that apply to all of the operations) you'll use the Service Attribute button to bring up that dialog to select those options, whereas for operations attributes (which only apply to specific methods of the service) you'll use the Operations Attribute button and it's resulting dialog.Under Service Behavior attributes, I've enabled.
I've done that primarily for debugging purposes. Once you've got the web service working and want to move it to production you'll want to turn that off.Figure 11 - WCF Service Behavior Attributes DialogI've also checked the option. By default, WCF services use the.
ASP.Net web services (what PowerBuilder Native uses for web services) uses the XmlSerializerFormat and can't properly handle the response from the DataContractSerializer. The XMLSerializerFormat option in WCF allows us to create a WCF service that uses a serializer that older technology clients like PowerBuilder Native can understand.Under Operation Attributes, the attribute is set for us by the project when we alias the name of the method. What I've done in addition to that is set the attribute. That forces the method to be invoked under a single threaded apartment (STA) threads.
By default, WCF uses multi-threaded apartment (MTA) threads.Figure 12 - WCF Operations Behavior Attributes DialogThe only reason we need to do this is that, for reasons I'm not clear on, PowerBuilder.Net includes references to WPF classes when you create a web service proxy. Since WPF is UI technology, if you don't select this options you'll get a.Net exception that indicates. The calling thread must be STA, because many UI components require this.That's because.Net notices the references to WPF classes in the project.
It may be possible to remove those references, but I haven't attempted that yet. Of course, if you're using Visual Studio.Net to create the proxy WCF web service you shouldn't have this issue because Visual Studio.Net won't create such references.Do a full build on the WCF Service. Once you've done that, you can go back into the WCF Service project, go to the Run tab, and point the 'Application' property to the wcfservicehost.exe file that got deployed with the build.Figure 13 - WCF Service Run Options. That's the bare minimum of a PowerBuilder Native application. Now lets create a Grid Datawindow that uses our new proxy web service.After you've selected New - DataWindow - Grid, select web service as the source.Figure 18 - New Web Service Based DataWindowOn the next page in the wizard, enter the same value for the WSDL that you gave SOAPUI earlier.Figure 19 - Web Service DataWindow Service URL DialogOn the next page, there should only be one service, select it.Figure 20 - Web Service DataWindow Service SelectionNow you need to select the method you want to call. Choose the Search method (or whatever you called it).Figure 21 - Web Service DataWindow Method SelectionOn the next page you'll need to select what data the datawindow is going to show.
In this case there's only one option, the result set from the service. Select it and hit Next.Figure 22 - Web Service DataWindow Data Selection.
Said.How about Bruce?I want to consume a web service that returns me nested structures:Structure A (string A1, string A2, structure B)Structure B (string B1, structure C)Structure C (string C1, string C2, string Cxml)I only get A1 and A2, and structure B has no register, so structure C has no regress either.I've tried the web service with java and alli if it returns all structures with values.Consumption of web service with PB 11.5 if executed well. It is SOAP 1.1, in PB when implementing the web service are created: the service and 4 OBJECTS NOT VISUAL (these are the structures that I mention)Please, your help so that you can receive the structure of the web service.Thank you. Said.I installed PB 12.6 on a laptop with Windows 10 64bits, in addition I installed the Windows SDK.Net Framework. Said.Using.Net Engine and hacking the internal call to 'wsdl.exe', PB was able to create objects/proxies described in SOAP12 WSDL. Steps I made:Renamed original 'wsdl.exe' to 'wsdl.original.exe'.Created a PB app and named it 'wsdl.exe'. Bruce Armstrong is a development lead with Integrated Data Services (IDS). Prior to joining IDS 14 years ago, he was an independent consultant for 15 years doing PowerBuilder development for companies such as Rockwell, Hughes, Boeing, Western Asset Management, Investment Technology Group and Johnson & Johnson.
He has been using PowerBuilder since version 1.0.B. He was a charter member of TeamSybase (formerly TeamPS), a PowerBuilder MVP, an SAP Mentor and now and Appeon MVP. He was a contributing author to SYS-CON's PowerBuilder 4.0 Secrets of the Masters and the editor of SAMs' PowerBuilder 9: Advanced Client/Server Development. He has contributed numerous articles to the PowerBuilder Developer's Journal (PBDJ) and the ISUG Tech Journal. He served as the editor-in-chief of PBDJ from 2004 to 2013 and served for a while as a technical editor for the ISUG Tech Journal.
He has done sessions on PowerBuilder at most TechWaves, SAP TechEd and Appeon Elevate conferences since 2004, at local user group meetings in Columbia, Germany, Belgium, Switzerland, England, Italy and France and numerous webcasts.
This content is part of the series: Create stand-alone web services applications with Eclipse and Java SE 6, Part 1Stay tuned for additional content in this series. Before you start About thisseriesThis tutorial series demonstrates how to create a stand-alone web servicesserver and client application that you can easily run from the commandline with Java SE 6 rather than from within Web application servercontainers.
Using a simple Hello World example, you'll leverage theEclipse IDE, Java SE 6, and Apache Ant to easily create fully functioningweb services server and client applications. You'll also use the TCP/IPMonitor to examine the communication traffic between the server andclient, and use the Eclipse Web Services Explorer tool to test the webservice. About this tutorialThis tutorial, Part 1 of the series, introduces you to publishing a webservice application using the Eclipse IDE, Java SE 6, and Ant. It lays thegroundwork for Part 2, which describes the creation of the web servicesclient application. Select the Use default JRE radio button if it waspreviously selected by default; otherwise select the Use aproject specific JRE radio button, ensuring that it'sJava SE 6.
Click Finish to associate your project with the JavaJDK you installed earlier. If you're prompted to switch Java perspective, clickYes.Create the serverFirst you need to create a Java package to house your Java classes:.
Select File New Package. When the New Java Package window opens, enter a name for the package,such as com.myfirst.wsServer, as shown in Figure 7. Creating apackage. When you're finished, you can stop the web service by clicking the redsquare in the Eclipse Console view. However, to continue the tutorialthe web service needs to remain running.Test the serverNext you use the Eclipse Web Services Explorer tool to invoke theoperations of a web service via native WSDL and SOAP to test thegetGreeting method of the web service you just created.
You may need to change to the Java EE perspective. ClickWindow Open Perspective Other. When the window appears, select Java EE. Select Run Launch the Web Services Explorer.Maximize the view by double-clicking its tab.
You should see thescreen shown in Figure 14.Figure 14. The Web ServicesExplorer. SummaryCreating, generating, and publishing a web service server is as simple asusing Eclipse and, of course, Java SE 6. Stay tuned for Part 2 of thistutorial series where you'll build the stand-alone client to use with thisstand-alone web service server. Appendix: A brief overview of web servicesterms and acronyms Web serviceAccording to W3C, a web service is the 'software system designed tosupport interoperable Machine to Machine interaction over a network.' Inother words, web services are programmatic interfaces used forapplication-to-application communication.
Typically, they are used as Webapplications that enable the communication between computers over anetwork, such as the Internet.Clients and servers communicate using XML messages that follow the SOAPstandard. That is, web services use XML to code and decode data and SOAPto transport it using open protocols. Two of the basic elements of webservices platforms are SOAP and WSDL. XMLExtensible Markup Language (XML) lets users define their own elements. It'sa general purpose specification facilitating the sharing of structureddata across different information systems, typically across a network. XMLis designed to carry information and not to display it.
In other words,XML does not actually do anything other than to structure, store, andtransport information; it's just plain text. SOAPSOAP used to stand for Simple Object Access Protocol, but this was droppedin version 1.2 because it was believed to be too misleading. It's alightweight communication protocol that lets applications exchangeinformation over networks using XML, or more simply, for accessing a webservice.
SOAP allows applications to communicate with each otherregardless of which operating system they're running on and whatprogramming language they were written in. WSDLA WSDL is an application-readable Web Services Description Language.
It'sused to describe the web service's features and how it should be called bythe client application. That is, it describes all the methods and itssignatures, the namespaces, plus the handling Uniform Resource Identifier(URI) for the web service in an XML document. The URI names a resource ona network.