问题:
我继承了一个用 PHP 调用 C# windows 服务的软件。它不能正常工作,所以我刚刚开始使用 WCF 和 SOAP。
我的主要问题是我无法使用 PHP 和 Soap 调用 Windows 服务。当我尝试它时,PHP 崩溃了。
我完成了 microsoft 教程: https ://docs.microsoft.com/en-us/dotnet/framework/wcf/getting-started-tutorial 当我使用教程中描述的 C# 客户端时,一切都像魅力一样工作。我添加了一个安装程序以使整个程序可作为 Windows 服务使用。长话短说,在 C# 中,一切都按预期工作。
我假设它只是没有为 SOAP 调用正确配置。我已经通读了:http ://www.rizalalmashoor.com/blog/calling-a-wcf-service-from-php/但我仍然无法让它运行。
问题:
源代码在下面。我想先提出我的问题:
1)我在基地址公开服务,对吗?
http://localhost:1234/GettingStartedLib/CalculatorService
2) http 端点为空。PHP 代码中的soapURL 是否正确?
3)有没有办法调试soap调用?即使我在 ZendStudio 中将它作为 CLI 应用程序进行调试,我也没有得到任何进一步的信息。
如果需要或没有得到充分解释,我很乐意提供更多信息。
- 在有人回答之前:在 php.ini 中启用了 Soap。已经检查过了。
源代码:
PHP:
$soapURL = 'http://localhost:1234/GettingStartedLib/CalculatorService?wsdl';
$soapAttributes = array('soap_version' => SOAP_1_1);
$result = new SoapClient($soapURL, $soapAttributes);
WCF库的配置:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true"/>
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="GettingStartedLib.CalculatorService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:1234/GettingStartedLib/CalculatorService"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="" binding="basicHttpBinding" contract="GettingStartedLib.ICalculator">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2"/>
</startup>
</configuration>
C#接口
namespace GettingStartedLib
{
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator {
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
[OperationContract]
string SoapCall();
}
}
C# 服务本身:
namespace GettingStartedLib
{
public class CalculatorService : ICalculator
{
public double Add(double n1, double n2) {
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
// Code added to write output to the console window.
Console.WriteLine("Return: {0}", result);
return result;
}
public double Subtract(double n1, double n2) {
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Multiply(double n1, double n2) {
double result = n1 * n2;
Console.WriteLine("Received Multiply({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Divide(double n1, double n2) {
double result = n1 / n2;
Console.WriteLine("Received Divide({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public string SoapCall() => "SoapCall";
}
}