使用Com和Delphi在c#类库中使用HTTPS服务

本文关键字:HTTPS 服务 类库 Com Delphi 使用 | 更新日期: 2023-09-27 18:05:36

我想使用一个https web服务。

在c#中,我可以在大约10行代码中实现这个。

在Delphi XE5中,这是一个非常令人头痛的问题,并且是证书存储和加密的混乱。我需要能够在Delphi XE5中使用它。

我的想法是在c#类库中坚持(简单)调用web服务,然后通过Delphi使用CreateOleObject实例化它。类库为regasm library.dll /codebasegacutil -i library.dll

我的问题似乎是,当从c#中消费web服务时,它非常依赖于存储在app.config文件中的端点和绑定设置。问题是,是因为我使用Delphi和COM这个配置文件读取出错(我得到错误:Could not find endpoint element with name...)。

我尝试了MyDelphiTestApp.exe.configlibrary.dll.config的各种排列,它们似乎都无法读取(app.config文件的副本,从类库项目中具有正确的数据)。我在运行时调试了c#类库,看看它认为配置文件在哪里,然后确保那里有一个,但它仍然失败。

谁能给我一个解决方案或在正确的方向推动?

编辑:5月30日。谢谢你的帮助。我的代码当前位于:
        var binding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential);
        binding.SendTimeout = new TimeSpan(0, 0, 0, 0, 100000);
        binding.OpenTimeout = new TimeSpan(0, 0, 0, 0, 100000);
        binding.MaxReceivedMessageSize = 10000;
        binding.ReaderQuotas.MaxStringContentLength = 10000;
        binding.ReaderQuotas.MaxDepth = 10000;
        binding.ReaderQuotas.MaxArrayLength = 10000;
        X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadOnly);
        X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByThumbprint, "XXXXXXXXXXXXXXXXXXXXXXXXXX", false);
        store.Close();
        if (certs.Count <= 0)
            return "Could not find certificate";
        AddressHeader addressHeader1 = AddressHeader.CreateAddressHeader("service1", "https://wibble.com/Service", 1);
        AddressHeader[] addressHeaders = new AddressHeader[1] { addressHeader1 };
        AddressHeaderCollection addressHeaderColl = new AddressHeaderCollection(addressHeaders);
        var epIdentity = new X509CertificateEndpointIdentity(certs[0]);
        EndpointAddress remoteAddress = new EndpointAddress(new Uri("https://wibble.com/Service/DataService.svc"), epIdentity, addressHeaderColl);
        AiropsScheduleDataServiceClient client = new AiropsScheduleDataServiceClient(binding, remoteAddress);

        var defaultCredentials = client.Endpoint.Behaviors.Find<ClientCredentials>();
        client.Endpoint.Behaviors.Remove(defaultCredentials); //remove the default credentials
        var loginCredentials = new ClientCredentials();
        loginCredentials.UserName.UserName = Username;
        loginCredentials.UserName.Password = Password;
        client.Endpoint.Behaviors.Add(loginCredentials); //Add new credential to the proxy
        ExportScheduleDataRequest request = new ExportScheduleDataRequest();
        ExportScheduleDataResponse response = client.ExportScheduleData(request);

…但这给了我一个Delphi客户端错误

"无法打开安全通道,因为与远程端点的安全协商失败。这可能是由于用于创建通道的EndpointAddress中不存在或不正确地指定了endpointentity。请验证由EndpointAddress指定或暗示的endpointentity是否正确标识了远程端点"

我又迷路了

使用Com和Delphi在c#类库中使用HTTPS服务

我不知道你在XE5中遇到了什么麻烦,但要回答你的问题,你可以在c#代码中执行以下操作,通过代码来进行绑定,而不是在app.config文件中进行绑定:

  var binding = new WSHttpBinding();
  binding.SendTimeout = new TimeSpan(0, 0, 0, 0, 100000);
  binding.OpenTimeout = new TimeSpan(0, 0, 0, 0, 100000);
  binding.MaxReceivedMessageSize = 10000;
  binding.ReaderQuotas.MaxStringContentLength = 10000;
  binding.ReaderQuotas.MaxDepth = 10000;
  binding.ReaderQuotas.MaxArrayLength = 10000;
  // Set the security mode
  binding.Security.Mode = SecurityMode.Transport;
  var endpoint = new EndpointAddress("http://localhost:57102/MyService.svc");
  var myClient = new WebServiceclient(binding, endpoint);

你可以根据需要更改值,如果你想使用BasicHttpBinding或其他。

由于这些值在代码中,您可以直接从Delphi应用程序传递它们。