Recent

Author Topic: How to consume WCF service  (Read 11896 times)

Max JRB

  • New Member
  • *
  • Posts: 11
    • JaxmaxBlogIT
How to consume WCF service
« on: February 26, 2013, 05:08:32 am »
Hi! I have a WCF service built on C# hosted on IIS server, I would like to make a client to consume this service on Lazarus, I haven't worked before with Services on Lazarus, so if there's an example or how to i'd appreciate it

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: How to consume WCF service
« Reply #1 on: February 26, 2013, 07:44:27 am »
Don't know what a WCF service is ;)

If it's SOAP/XML, have a look at Web Services Toolkit (WST) on the wiki.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

binfch

  • New Member
  • *
  • Posts: 22
Re: How to consume WCF service
« Reply #2 on: February 26, 2013, 09:30:48 am »
Hi there

If $ is not an issue you might also try http://www.remobjects.com/ro/. The SDK works with freepascal...

Cheers,
Peter

Michael Collier

  • Sr. Member
  • ****
  • Posts: 285
Re: How to consume WCF service
« Reply #3 on: March 01, 2013, 04:13:22 am »
I use WST myself but can't remember if I have connected lazarus client to WCF server. I have done it the other way around, C# client to lazarus WST server.

Learning WST was a bit tricky because the examples need modifying before they can be compiled (hard coded paths ) and some files need to be re-generated using the type library tool or you get metadata signature errors.

Can you publish the URL of your application and maybe someone could try and connect from a lazarus WST client for you? Private message me if you don't want the URL to be public. I can't promise anything but I'll take a look.

otorres

  • Jr. Member
  • **
  • Posts: 94
Re: How to consume WCF service
« Reply #4 on: March 01, 2013, 05:20:29 am »
And remember, WCF need configuration for external clients, because by default you cant use it with a SOAUI or Ardana Storm (Web services testers).


Michael Collier

  • Sr. Member
  • ****
  • Posts: 285
Re: How to consume WCF service
« Reply #5 on: March 09, 2013, 03:32:01 pm »
Hi! I have a WCF service built on C# hosted on IIS server, I would like to make a client to consume this service on Lazarus, I haven't worked before with Services on Lazarus, so if there's an example or how to i'd appreciate it

I tried this for you, may help others too..

A public webservice is available here to convert temperatures: http://www.webservicex.net/WS/WSDetails.aspx?WSID=31&CATID=13

1. To use in Lazarus Webserver Toolkit I copied their WSDL info (Web Service Definition Language) to my local drive, called it convert.wsdl. It is XML and looks like this:

convert.wsdl
Code: [Select]
<?xml version="1.0" encoding="utf-8"?>
<definitions name="http://www.webserviceX.NET/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://www.webserviceX.NET/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.webserviceX.NET/">
  <types>
    <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.webserviceX.NET/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.webserviceX.NET/">
      <xsd:complexType name="ConvertTemp">
        <xsd:sequence>
          <xsd:element name="Temperature" type="xsd:double"/>
          <xsd:element name="FromUnit" type="tns:TemperatureUnit"/>
          <xsd:element name="ToUnit" type="tns:TemperatureUnit"/>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:complexType name="ConvertTempResponse">
        <xsd:sequence>
          <xsd:element name="ConvertTempResult" type="xsd:double"/>
        </xsd:sequence>
      </xsd:complexType>
      <xsd:simpleType name="TemperatureUnit">
        <xsd:restriction base="xsd:string">
          <xsd:enumeration value="degreeCelsius"/>
          <xsd:enumeration value="degreeFahrenheit"/>
          <xsd:enumeration value="degreeRankine"/>
          <xsd:enumeration value="degreeReaumur"/>
          <xsd:enumeration value="kelvin"/>
        </xsd:restriction>
      </xsd:simpleType>
      <xsd:element name="_double" type="xsd:double"/>
    </xsd:schema>
  </types>
  <message name="ConvertTemp">
    <part name="ConvertTemp" type="tns:ConvertTemp"/>
  </message>
  <message name="ConvertTempResponse">
    <part name="ConvertTempResponse" type="tns:ConvertTempResponse"/>
  </message>
  <portType name="ConvertTemperatureSoap">
    <documentation>
      <GUID value="{682745A9-8683-42ED-832A-CE9DF2E67FA9}"/>
    </documentation>
    <operation name="ConvertTemp">
      <input message="tns:ConvertTemp"/>
      <output message="tns:ConvertTempResponse"/>
    </operation>
  </portType>
  <binding name="ConvertTemperatureSoap" type="tns:ConvertTemperatureSoap">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="ConvertTemp">
      <soap:operation soapAction="http://www.webserviceX.NET/ConvertTemp"/>
      <input>
        <soap:body use="literal" namespace="http://www.webserviceX.NET/"/>
      </input>
      <output>
        <soap:body use="literal" namespace="http://www.webserviceX.NET/"/>
      </output>
    </operation>
  </binding>
  <service name="ConvertTemperatureSoap">
    <port name="ConvertTemperatureSoapPort" binding="tns:ConvertTemperatureSoap">
      <soap:address location="http://www.webservicex.net/ConvertTemperature.asmx"/>
    </port>
  </service>
</definitions>

2. Create a new Lazarus project (and assuming you have installed the WST design type package) go to Menu/Project/Web_Services_Toolkit/Type_Library_Editor and open the saved convert.WSDL file.

3. The type library editor displays the Lazarus units needed to interact with the webservice, so save them all by selecting "Save Generated Files" from within the type library editor.

4. Include the generated files in your own project uses clause:

Code: [Select]
  // files generated by wst type library editor --
  , convert
  , convert_binder
  , convert_imp
  , convert_proxy
  // --------------------------------------------- 

5. You will also need these in your uses clause
Code: [Select]
  // SYNAPSE
    , synapse_http_protocol
  // WST
  , soap_formatter   

6. The code to Connect to the conversion service with some parameters looks likes this (requires 1 button & 1 label on the form):

Code: [Select]
procedure TForm1.Button1Click(Sender: TObject);
var myConvertClient    : ConvertTemperatureSoap  ; // connection
    myConvertTemp_Type : ConvertTemp_Type        ; // parameter in
    myResult           : ConvertTempResponse     ; // result out
begin
  myConvertClient    := wst_CreateInstance_ConvertTemperatureSoap( ) ;
  myConvertTemp_Type := ConvertTemp_Type.Create()                    ;
  // prepare: convert zero degrees celcius to farenheit
  myConvertTemp_Type.Temperature := 0.0              ;
  myConvertTemp_Type.FromUnit    := degreeCelsius    ;
  myConvertTemp_Type.ToUnit      := degreeFahrenheit ;
  // perform the conversion
  myResult                       := myConvertClient.ConvertTemp( myConvertTemp_Type );
  // display the result (should = 32)
  Label1.Caption                 := FloatToStr( myResult.ConvertTempResult  ) ;
end;

7. Your application will need to register HTTP Transport e.g. on the form create or initialization.

Code: [Select]
procedure TForm1.FormCreate(Sender: TObject);
begin
  // WST
  SYNAPSE_RegisterHTTP_Transport();
end;   

8. Your project will need the source for WST and in this case synapse, but you could also use other (e.g. Indy). So inlcude the paths to the source in your project source path:

..\third_party\wst;..\third_party\synapse40\source\lib

I will zip and include the source for this project, you will need to modify these paths to suit your own environment.

9 . Here is the entire code:

Code: [Select]
unit main;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls

  // SYNAPSE
  , synapse_http_protocol
  // WST
  , soap_formatter
  {
  , binary_formatter
  , json_formatter
  , xmlrpc_formatter
  }
  // files generated by wst type library editor --
  , convert
  , convert_binder
  , convert_imp
  , convert_proxy
  // ---------------------------------------------

  ;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;


implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var myConvertClient    : ConvertTemperatureSoap  ; // connection
    myConvertTemp_Type : ConvertTemp_Type        ; // parameter in
    myResult           : ConvertTempResponse     ; // result out
begin
  myConvertClient    := wst_CreateInstance_ConvertTemperatureSoap( ) ;
  myConvertTemp_Type := ConvertTemp_Type.Create()                    ;
  // prepare: convert zero degrees celcius to farenheit
  myConvertTemp_Type.Temperature := 0.0              ;
  myConvertTemp_Type.FromUnit    := degreeCelsius    ;
  myConvertTemp_Type.ToUnit      := degreeFahrenheit ;
  // perform the conversion
  myResult                       := myConvertClient.ConvertTemp( myConvertTemp_Type );
  // display the result (should = 32)
  Label1.Caption                 := FloatToStr( myResult.ConvertTempResult  ) ;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // WST
  SYNAPSE_RegisterHTTP_Transport();
end;

end. 



alfasud

  • Newbie
  • Posts: 2
Re: How to consume WCF service
« Reply #6 on: March 27, 2014, 03:46:36 pm »
Michael

I used your method to consume C# web service and it worked fine. But it seems that  WST library has some problems.
Namely when using decimal number format or special characters  in strings.
I wrote an example project using well known web service form this link http://www.drbob42.com/examines/examin45.htm

Demo project is included.

Thank you in advance

Michael Collier

  • Sr. Member
  • ****
  • Posts: 285
Re: How to consume WCF service
« Reply #7 on: April 01, 2014, 08:16:18 am »
alfasud

I'll try out special characters and decimal formats in a web service I'm working on, I notice you are using SOAP formatter, have you tried any others such as binary. I have had problems in the past sending data and had to switch to different formatter.

Michael Collier

  • Sr. Member
  • ****
  • Posts: 285
Re: How to consume WCF service
« Reply #8 on: April 01, 2014, 04:54:40 pm »
I added an echo_string function to a new webservice and it echos characters from the windows character map tool e.g. "Æ". This is all done in Lazarus on windows XP. Can you describe your problem in a bit more detail so I can try.

alfasud

  • Newbie
  • Posts: 2
Re: How to consume WCF service
« Reply #9 on: April 02, 2014, 08:53:12 am »
Thank You for quick answer

I used same char as you did, but with DrBob's service. Here is wsdl link: http://www.ebob42.com/cgi-bin/wseBob42CSharp.asmx?wsdl

I tried this on win7 64, XP SP3 and Linux 12.04LTS. You can see results on enclosed pics. 

P.S
I have Slovenian language and keyboard, so I use comma as decimal separator.
If you change dec separator according to your language, you should get same error for decimal format, but double should be fine.
« Last Edit: April 02, 2014, 09:21:15 am by alfasud »

Michael Collier

  • Sr. Member
  • ****
  • Posts: 285
Re: How to consume WCF service
« Reply #10 on: April 03, 2014, 10:39:07 am »
I tried strings with drBob page and get "?" back for special characters same as you.

I'm totally guessing, but since it works lazarus <-> lazarus and fails lazarus <-> delphi then maybe the "fault" if any is at the delphi end?

You could try a C# client, if that fails then let DrBob know and get help there?

I have attached a C# project that you can modify to echo strings to drBob service. It is a project with just 1 form and the soap service already created. You will need to add a button and edit boxes and call the service yourself. Google for "WSDL C# Client".

The author of WST may help, they have a google group here https://groups.google.com/forum/#!forum/wst-list

 

TinyPortal © 2005-2018