I am done doing my first PHP to .NET interoperability example. In this example a PHP page calls a windows communication foundation (WCF) service in .NET
Here is what we want to create:
First create a "out of the box" windows communication foundation (WCF) WCF service library project.
Then, modify the project files according to the files posted bellow.
My server side WCF code looks like this:
1) Service1.cs –
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfServiceLibrary1
{
// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in App.config.
public class Service1 : IService1
{
public string GetData()
{
return string.Format("Time on server is " + System.DateTime.Now.ToString());
}
}
}
2) IService1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfServiceLibrary1
{
// NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in App.config.
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData();
// TODO: Add your service operations here
}
}
The server side WCF application configuration file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<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="WcfServiceLibrary1.Service1" behaviorConfiguration="WcfServiceLibrary1.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
</baseAddresses>
</host>
<!– Service Endpoints –>
<!– Unless fully qualified, address is relative to base address supplied above –>
<endpoint address ="" binding="basicHttpBinding" contract="WcfServiceLibrary1.IService1">
<!–
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 name="WcfServiceLibrary1.Service1Behavior">
<!– To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment –>
<serviceMetadata httpGetEnabled="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>
</configuration>
Note my blog post about the importance of setting this WCF service binding to basicHttpBinding
The PHP side of the application code looks like this:
<h1>
<?php
try{
$client = new
SoapClient(
"http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary1/Service1/?wsdl"
);
$webService = $client->GetData();
$wsResult = $webService->GetDataResult;
print $wsResult;
} catch (Exception $e) {
print ‘Caught exception: ‘. $e->getMessage(). "\n";
}
?>
</h1>
The only thing you need to modify is the URL parameter passed to the SoapClient to match your WCF service URL.
If you want to pass parameters to the WCF web service call please see this blog post.
If you have any questions please post a reply.
ok but what should I do when service wsdl has 2 endpoints one over basicHttp and one over wsHttp (with mtom encoding)?
How can I tell php to choose the basicHttpBinding, coz right now I have this error “Fatal error: Uncaught SoapFault exception: [HTTP] Cannot process the message because the content type ‘text/xml; charset=utf-8’ was not the expected type ‘multipart/related; type=”application/xop+xml”‘
You should use basicHttp on both endpoints.
Have you tried this from two different networks? i.e. PHP client is hosted on a network A and the WCF Service is hosted on Network B and the URL is opened up to the PHP application for the port mentioned in your URL. Does this setup work?
You might need to open the right ports for cross network connections to work…
I have a wcf service method with an object of a class as input parameter. This class has property that is an array of objects of other class:
void Request( RequestInputParam in);
class RequestInputParam
{
public ArrayClass[] obj;
}
How can I pass such param from PHP client to .NET WCF service.