简体   繁体   English

如何使用Delphi 2010导入https webservice(wcf)?

[英]How can i import a https webservice (wcf) with Delphi 2010?

I have a problem so i wanna help from you. 我有一个问题,所以我想帮助你。 There is a webservice and it's url : https://kps.saglik.gov.tr/Services/KPSTestServices.svc 有一个web服务,它的网址是: https//kps.saglik.gov.tr/Services/KPSTestServices.svc

We can import this url on visual studio c# easily, but we couldn't import it on delphi 2010. 我们可以轻松地在visual studio c#上导入这个url,但我们无法在delphi 2010上导入它。

Also we have a user id and password from saglik.gov.tr, but the result is same : can't import this service. 我们还有来自saglik.gov.tr的用户ID和密码,但结果是相同的:无法导入此服务。 What can we do now ? 我们现在能做什么 ?

Thanks for any idea from at the moment. 感谢您的任何想法。

Visual Studio Sample : https://kps.saglik.gov.tr/kps_ornek1.zip Visual Studio示例: https//kps.saglik.gov.tr/kps_ornek1.zip


I was able to import files to your local hard disk recording. 我能够将文件导入到本地硬盘录制中。

When I call service , Now I get the https connection failed error. 当我呼叫服务时,现在我得到https连接失败错误。

Xml created by the WCFStorm (http://www.wcfstorm.com/wcf/home.aspx) 由WCFStorm创建的Xml (http://www.wcfstorm.com/wcf/home.aspx)

Header 

POST https://kps.saglik.gov.tr/Services/KPSTestServices.svc HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Host: kps.saglik.gov.tr
Content-Length: 1256
Expect: 100-continue
Connection: Keep-Alive


<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><s:Header><a:Action s:mustUnderstand="1">http://www.saglik.gov.tr/KPS/2011/KPSServices/TcKimlikNoIleKisiSorgula</a:Action><a:MessageID>urn:uuid:b99c1ef4-9e44-42b9-ae1f-9844bfc0f997</a:MessageID><a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address></a:ReplyTo><a:To s:mustUnderstand="1">https://kps.saglik.gov.tr/Services/KPSTestServices.svc</a:To><o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><u:Timestamp u:Id="_0"><u:Created>2011-09-13T11:17:27.234Z</u:Created><u:Expires>2011-09-13T11:22:27.234Z</u:Expires></u:Timestamp><o:UsernameToken u:Id="uuid-d7a725d3-aa3c-4336-8651-304ecdb8d5e0-4"><o:Username>myUserName</o:Username><o:Password o:Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">myPassword</o:Password></o:UsernameToken></o:Security></s:Header><s:Body><TcKimlikNoIleKisiSorgula xmlns="http://www.saglik.gov.tr/KPS/2011"><tcNo>1842715****</tcNo></TcKimlikNoIleKisiSorgula></s:Body></s:Envelope>

Response XML 响应XML

Header
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 1519
Content-Type: application/soap+xml; charset=utf-8
Server: Microsoft-IIS/7.5
Set-Cookie: ASP.NET_SessionId=0vdbbkozgztz4falycku4gr0; path=/; HttpOnly
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 13 Sep 2011 11:19:40 GMT

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><s:Header><a:Action s:mustUnderstand="1">http://www.saglik.gov.tr/KPS/2011/KPSServices/TcKimlikNoIleKisiSorgulaResponse</a:Action><a:RelatesTo>urn:uuid:b99c1ef4-9e44-42b9-ae1f-9844bfc0f997</a:RelatesTo><o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><u:Timestamp u:Id="_0"><u:Created>2011-09-13T11:19:41.255Z</u:Created><u:Expires>2011-09-13T11:24:41.255Z</u:Expires></u:Timestamp></o:Security></s:Header><s:Body><TcKimlikNoIleKisiSorgulaResponse xmlns="http://www.saglik.gov.tr/KPS/2011"><TcKimlikNoIleKisiSorgulaResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Hata i:nil="true"/><Sonuc><Ad>MUSTAFA</Ad><AileSiraNo>12</AileSiraNo><AnaAd>LEYLA</AnaAd><BabaAd>OSMAN</BabaAd><BireySiraNo>*</BireySiraNo><CiltAd>-</CiltAd><CiltKod>-</CiltKod><Cinsiyet>Erkek</Cinsiyet><Din i:nil="true"/><DogumTarihi>21.9.0000</DogumTarihi><DogumYer>*</DogumYer><Durum>Açık</Durum><Hata i:nil="true"/><IlAd>*</IlAd><IlKod>*</IlKod><IlceAd>Abana</IlceAd><IlceKod>*</IlceKod><MedeniHal>Bekar</MedeniHal><OlumTarih>0.0.0</OlumTarih><Soyad>*</Soyad><TCKimlikNo>18427***</TCKimlikNo><Yakinlik>Kendisi</Yakinlik></Sonuc></TcKimlikNoIleKisiSorgulaResult></TcKimlikNoIleKisiSorgulaResponse></s:Body></s:Envelope>

Delphi 2010 Delphi 2010

My Request 我的请求

CONNECT kps.saglik.gov.tr:443 HTTP/1.0
User-Agent: Borland SOAP 1.2
Host: kps.saglik.gov.tr:443
Content-Length: 0
Proxy-Connection: Keep-Alive
Pragma: no-cache

No XML 没有XML

My Response 我的回复

Header 
HTTP/1.1 502 Unable to Secure Connection
Via: 1.1 SYSTMG07
Connection: Keep-Alive
Proxy-Connection: Keep-Alive

No XML 没有XML

You need to point delphi towards the WSDL of the service. 您需要将delphi指向服务的WSDL。 just append ?wsdl to the end of the first URL you gave: https://kps.saglik.gov.tr/Services/KPSTestServices.svc?wsdl and open this URL. 只需将?wsdl附加到您提供的第一个URL的末尾: https ://kps.saglik.gov.tr/Services/KPSTestServices.svc?wsdl并打开此URL。

Save the file as a wsdl file and import it using: File -> New -> Other -> Delphi Projects -> Webservices -> WSDL Importer . 将文件另存为wsdl文件并使用以下命令导入: File - > New - > Other - > Delphi Projects - > Webservices - > WSDL Importer

Please note: when the webservice changes you need to reimport. 请注意:当Web服务发生变化时,您需要重新导入。 Also, using the webservice this way, you might need to deploy the wsdl with your application, depending on wether or not you are using the wsdl when consuming the webservice. 此外,以这种方式使用Web服务,您可能需要在应用程序中部署wsdl,具体取决于您是否在使用Web服务时使用wsdl。

Maybe I am a little bit pessimistic about Delphi SOAP support, but I think this will be easier to solve using a "proxy" service written in C# (or Java, depending on available developer resources). 也许我对Delphi SOAP支持有点悲观,但我认为使用C#(或Java,取决于可用的开发人员资源)编写的“代理”服务更容易解决。

I have used a 'proxy' solution succesfully for the integration of a Microsoft Dynamics CRM system. 我成功地使用了“代理”解决方案来集成Microsoft Dynamics CRM系统。 After many attempts to solve it in Delphi, we finally wrote a simple C# application which reads input data from files (created from the Delphi app) and then invokes the web service operations using the data from these files. 经过多次尝试在Delphi中解决它之后,我们最终编写了一个简单的C#应用​​程序,它从文件中读取输入数据(从Delphi应用程序创建),然后使用这些文件中的数据调用Web服务操作。

Fortunately this was only a very simple one-way interface. 幸运的是,这只是一个非常简单的单向界面。 For advanced requirements, the Delphi app could communicate over a TCP based protocol (HTTP) using XML or JSON payload. 对于高级需求,Delphi应用程序可以使用XML或JSON有效负载通过基于TCP的协议(HTTP)进行通信。 For bidirectional data exchange, the Delphi application would have to run a HTTP server too, which can be implemented with Indy in a couple of code lines. 对于双向数据交换,Delphi应用程序也必须运行HTTP服务器,这可以通过几个代码行中的Indy来实现。 For bidirectional operation, using a messaging middleware like MSMQ (or one of the many open source message brokers like ActiveMQ or OpenMQ) can also be a good solution, because all applications can go offline for maintenance without the danger of message loss. 对于双向操作,使用消息中间件(如MSMQ(或ActiveMQ或OpenMQ等众多开源消息代理之一))也是一个很好的解决方案,因为所有应用程序都可以脱机进行维护而不会丢失消息。

I just went through a similar problem attempting to connect a D2007 client to a C# service. 我刚刚尝试将D2007客户端连接到C#服务时遇到了类似的问题。 The details I found were interesting. 我发现的细节很有趣。 First of all the Delphi importer seriously under performed. 首先,德尔福进口商严重执行。 I switched to RemObj and continued to have problems. 我切换到RemObj并继续遇到问题。 At the end of the day there seems to be 3 items of interest when making the call to a WCF C# web service from a Delphi App. 在一天结束时,从Delphi应用程序调用WCF C#Web服务时似乎有3个感兴趣的项目。 Those 3 items are as follows... 这3个项目如下......

1) Make sure on the Delphi side you have the Soap version set to 1.2 (this is the easy one) 1)确保Delphi端的Soap版本设置为1.2(这很容易)

2) The post command being generated was including an incorrect action. 2)生成的post命令包含不正确的操作。 needed: POST "http://URI/Service/Command" RemObj: POST urn:HCSConnect-WSHCSConnect#Ping Delphi: ---post command missing completely--- 需要:POST“http:// URI / Service / Command”RemObj:POST urn:HCSConnect-WSHCSConnect #Ping Delphi:--- post命令完全丢失---

What I did was change some details in the Rem Obj stuff and make it look like what I needed 我所做的是改变Rem Obj中的一些细节,使它看起来像我需要的东西

3) With the service I was using the soap envelope wants a header area that contains a definition of a few details. 3)使用肥皂信封的服务需要一个标题区域,其中包含一些细节的定义。 In my situation the most important items in this header turned out to be the "a:Action" and "a:To" tags. 在我的情况下,此标题中最重要的项目被证明是“a:Action”和“a:To”标签。 These tags are missing in the Delphi apps, RemObj or otherwise. Delphi应用程序,RemObj或其他方式中缺少这些标记。 So in my situations I am intercepting the xml and filling it in. 所以在我的情况下,我正在拦截xml并将其填入。

The solutions to the last 2 items are not so simple... if you are using Rem Obj you can read about how I fixed it and what you can do the RemObj forum. 最后两个项目的解决方案并不那么简单......如果你使用Rem Obj,你可以阅读我如何修复它以及你可以做什么RemObj论坛。

http://connect.remobjects.com/discussion/825/problem-calling-web-service-built-with-c http://connect.remobjects.com/discussion/825/problem-calling-web-service-built-with-c

.... last but not least ... .... 最后但并非最不重要的 ...

I also got the thing to work using direct calls... if you are not using RemObj and Delphi is being a pain you can always just build your post and xml yourself and send it. 我也使用直接调用工作...如果你不使用RemObj和Delphi很痛苦你总是可以自己构建你的帖子和xml并发送它。 Just like I did below... remember, post/xml/web it's all just plain text being sent back and forth. 就像我在下面做的那样...记住,发布/ xml / web它只是来回发送的纯文本。

procedure TMainForm.Button5Click(Sender: TObject);
  procedure HandleError(const errorCode: integer);
  var
    errorMessage: AnsiString;
  begin
    SetLength(errorMessage, 256);
    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_FROM_HMODULE,
                   Pointer(GetModuleHandle('wininet.dll')),
                   errorCode, 0, PChar(errorMessage), Length(errorMessage), nil);
    SetLength(errorMessage, StrLen(PChar(errorMessage)));
    raise Exception.Create(errorMessage);
  end;

  function BuildHeader: TStringStream;
  begin
    result := TStringStream.Create('');
    try
      result.WriteString('Content-Type: application/soap+xml;charset=UTF-8;action="http://Thermo.Connect/IHCSConnect/Ping"' + sLineBreak);
    except
      result.Free;
      raise;
    end;
  end;

  function BuildBody: TStringStream;
  begin
    result := TStringStream.Create('');
    with result do
      try
        WriteString('<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">' + sLineBreak);
        WriteString('<s:Header>' + sLineBreak);
        WriteString('<a:Action>http://Thermo.Connect/IHCSConnect/Ping</a:Action>' + sLineBreak);
        WriteString('<a:To>http://thermo-pc:2021/WSHCSConnect</a:To>' + sLineBreak);
        WriteString('</s:Header>' + sLineBreak);
        WriteString('<s:Body>' + sLineBreak);
        WriteString('<Ping xmlns="http://Thermo.Connect">' + sLineBreak);
        WriteString('</Ping>' + sLineBreak);
        WriteString('</s:Body>' + sLineBreak);
        WriteString('</s:Envelope>' + sLineBreak);
      except;
        result.Free;
        raise;
      end;
  end;

var
  InetRoot: HINTERNET;
  InetConnect: HINTERNET;
  Request: HINTERNET;
begin
  InetRoot := InternetOpen('GabeCode', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
    InetConnect := InternetConnect( InetRoot, 'thermo-pc:2021', 0, '',
                                    '', INTERNET_SERVICE_HTTP, 0, Cardinal(Self));
    try
      Request := HttpOpenRequest( InetConnect, 'POST', 'WSHCSConnect', 'HTTP/1.1', nil, nil,
                                  INTERNET_FLAG_KEEP_CONNECTION or INTERNET_FLAG_NO_CACHE_WRITE,
                                  0);
      try
        // build add header items to the post request
        with BuildHeader do
        try
          HttpAddRequestHeaders(Request, PChar(DataString), Length(DataString), HTTP_ADDREQ_FLAG_ADD);
        finally
          Free;
        end;

        // build the body of data being posted and send the post
        with BuildBody do
        try
          if not HttpSendRequest(Request, nil, 0, PChar(DataString), Length(DataString)) then
            HandleError(GetLastError);
        finally
          Free;
        end;

      finally
        InternetCloseHandle(Request);
      end;
    finally
      InternetCloseHandle(InetConnect);
    end;
  finally
    InternetCloseHandle(InetRoot);
  end;
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM