Basically I have the code from MSDN.
The code is:
using System;
using System.ServiceModel;
// This code generated by svcutil.exe.
[ServiceContract()]
interface IMath
{
[OperationContract()]
double Add(double A, double B);
}
public class Math : IMath
{
public double Add(double A, double B)
{
return A + B;
}
}
public sealed class Test
{
static void Main()
{
// Code not shown.
}
public void Run()
{
// This code is written by an application developer.
// Create a channel factory.
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://localhost/MathService/Ep1");
ChannelFactory<IMath> myChannelFactory = new ChannelFactory<IMath>(myBinding, myEndpoint);
// Create a channel.
IMath wcfClient1 = myChannelFactory.CreateChannel();
double s = wcfClient1.Add(3, 39);
Console.WriteLine(s.ToString());
((IClientChannel)wcfClient1).Close();
// Create another channel.
IMath wcfClient2 = myChannelFactory.CreateChannel();
s = wcfClient2.Add(15, 27);
Console.WriteLine(s.ToString());
((IClientChannel)wcfClient2).Close();
myChannelFactory.Close();
}
}
However based on my superficial understanding, it is a self host WCF. The above code is combining service code and client code together.
If the WCF is host in a server, we don’t know its internal struture at all. Then how to consume it in client side?
I used the code
ChannelFactory<IMath> myChannelFactory = new ChannelFactory<IMath>(myBinding, myEndpoint);
But intellisense doesn’t know IMath at all.
I am not strong on proxy, ChannelFactory etc. Now my question is that if the service IMath is host at http://www.someserver/IMath.svc, how to write code in client side to consume it?
Please don’t think adding web reference to the clent…
updated:
In the service wsdl:
I have something like:
<wsdl:binding name="BasicHttpBinding_iMath" type="tns:iMath">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="Add">
<soap:operation soapAction="http://tempuri.org/iMath/add" style="document" />
- <wsdl:input>
<soap:body use="literal" />
</wsdl:input>
- <wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
- <wsdl:operation name="LoadUnbillsFromOrion">
<soap:operation soapAction="http://tempuri.org/iMath/LoadUnbillsFromOrion" style="document" />
- <wsdl:input>
<soap:body use="literal" />
</wsdl:input>
- <wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name="Math">
- <wsdl:port name="BasicHttpBinding_iMath" binding="tns:BasicHttpBinding_iMath">
<soap:address location="http://wsvc01/Imath.svc" />
</wsdl:port>
</wsdl:service>
Basically, all you need to know is a binding and endpoint address on your client side.
To consume a WCF service you need to create a proxy. Unless you specifically need a reason to the ChannelFactory, it’s probably easier to create a “Client” class that inherits from ClientBase<>.
You then create an instance of your proxy suppling it an endpoint and binding in the constructor (or have the proxy automatically do it in it’s default, you can do whatever you want) to communicate with your WCF Service. You then just Open and Close your client object and then Call your Client.IMathOperation to perform an operation on the service. The ClientBase<> will handle Channel creation, disposing, pooling etc.
You’ll probably want to put in various wrapper and helper classes on the Client side to handle exceptions, testing your connection before trying to access it, encapsulating opening and closing channels etc. to make it less verbose to use on the client-side.