Server Side
Steps to create the Service definition (Contract):
- Open Notepad and add namespace System and System.ServiceModel. We need ServiceModel to specify a WCF service
- For WCF service we need to create an interface which will act as a proxy to the client. From the client, we need to replicate the proxy object and build the same interface again. After we declare the Interface we mark the Interface with ServiceContract, and the method to be exposed to outside using OperationContract.
- Next we create a concrete class for the same to define the class implementing the interface.
[ServiceContract] public interface IOperationSimpleWCF { [OperationContract] string MySimpleMethod(string inputText); } public class OperationSampleWCF : IOperationSimpleWCF { public string MySimpleMethod(string inputText) { Console.WriteLine("Message Received : {0}", inputText); Console.WriteLine(OperationContext.Current.RequestContext.RequestMessage.ToString()); return string.Format("Message from Server {0}", inputText); } }
Steps to host the service (Address , Binding):
To host the service in the server you need to know three inputs:
- Binding : This indicates how the service will be hosted. For basic soap operation with no security we need HttpBinding. We can also use other bindings as well.
- Address : Represents the location to host the service. When the service is hosted you can specify the qualified service path where the service will be hosted.
- Host the service using ServiceHost and Open the connection.
static void Main(string[] args) { BasicHttpBinding binding = new BasicHttpBinding(); Uri serviceUri = new Uri("http://localhost:8000"); ServiceHost host = new ServiceHost(typeof(OperationSampleWCF), serviceUri); host.AddServiceEndpoint(typeof(IOperationSimpleWCF), binding, "OperationService"); host.Open(); Console.WriteLine("Service is hosted to the Server"); Console.ReadLine(); host.Close(); }
So the uri where the service is hosted is http://localhost:8000/OperationService. You should notice the call AddServiceEndpoint is used to give the qualified address for the service. If you don’t specify AddServiceEndpoint the service will be posted to root path of Uri specified.
To Compile the Server application :
- Open Command prompt and navigate to the location where you save the File with code.
- To compile the program use csc with /r: to reference the System.ServiceModel.dll using (Say the file we save for code is ServerProgram.cs)
csc /r:” C:\windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\System.ServiceModel.dll” ServerProgram.cs - You will get the program compiled, and produce the Executable. Run the program.
Hence the service is running and waiting for the client to receive request.
Now its time to create our client application.
Client Side
Steps to create Client Application :
- First you need to mimic the ServiceContract interface in the client. If you want to check the Request Body you can use OperationContext.Current.RequestContext.RequestMessage, Or you can directly parse the soap contract using and create the Contract class yourself.
- Once we have created the Contract, we create an object of ChannelFactory which actually creates the interface between the client and the server. The ChannelFactory requires the Binding, and EndPointAddress. The endpoint address for our client will be http://localhost:8000/OperationService
- Finally we call CreateChannel to get the actual proxy object which is capable of calling the Remote server.
- Compile the Client
static void Main(string[] args) { Console.WriteLine("Press Enter to call Server"); Console.ReadLine(); BasicHttpBinding binding = new BasicHttpBinding(); ChannelFactory<IOperationSimpleWCF> factory = new ChannelFactory<IOperationSimpleWCF>(binding, new EndpointAddress("http://localhost:8000/OperationService")); IOperationSimpleWCF proxy = factory.CreateChannel(); string methodFromServer = proxy.MySimpleMethod("Hello"); Console.WriteLine(methodFromServer); Console.ReadLine(); } [ServiceContract] public interface IOperationSimpleWCF { [OperationContract] string MySimpleMethod(string inputText); }
Once we are done we need to compile the client again using csc.
csc /r:” C:\windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\System.ServiceModel.dll” ClientProgram.cs
Now open the two console side by side, and when you call the server from Client console, it updates the server console. Hence the server been called properly.
If you open the call to OperationContext.Current.RequestContext.RequestMessage.ToString() you can see the Soap envelope that is passed as request to the server from the client. It will look like :
<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"> <s:Header> <To s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">http://localhost:8000/OperationService</To> <Action s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">http://tempuri.org/IOperationSimpleWCF/MySimpleMethod</Action> </s:Header> <s:Body> <MySimpleMethod xmlns=\"http://tempuri.org/\"> <inputText>Hello</inputText> </MySimpleMethod> </s:Body> </s:Envelope>
Now if you change the Binding from BasicHttpBinding to WSHttpBinding the program outputs the same while the Request body changes with all the support of security features and the message passed within the Soap envelope will automatically been encrypted.
<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\" u:Id=\"_2\">http://tempuri.org/IOperationSimpleWCF/MySimpleMethod</a:Action> <a:MessageID u:Id=\"_3\">urn:uuid:b3edb9bc-6043-4c05-b540-794e5d61d505</a:MessageID> <a:ReplyTo u:Id=\"_4\"> <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address> </a:ReplyTo> <a:To s:mustUnderstand=\"1\" u:Id=\"_5\">http://localhost:8000/OperationService</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=\"uuid-ce693b53-159f-492e-b79a-f904abb878d8-11\"> <u:Created>2010-09-14T23:26:22.015Z</u:Created> <u:Expires>2010-09-14T23:31:22.015Z</u:Expires> </u:Timestamp> < c:SecurityContextToken u:Id=\"uuid-ff9818d2-87c0-4daa-ba54-ce07e283ca38-4\" xmlns:c=\"http://schemas.xmlsoap.org/ws/2005/02/sc\"> <c:Identifier>urn:uuid:2a3567f3-73e7-4f8d-9a5d-f2be8defae2f</c:Identifier> </c:SecurityContextToken> <c:DerivedKeyToken u:Id=\"uuid-ce693b53-159f-492e-b79a-f904abb878d8-9\" xmlns:c=\"http://schemas.xmlsoap.org/ws/2005/02/sc\"> <o:SecurityTokenReference> <o:Reference ValueType=\"http://schemas.xmlsoap.org/ws/2005/02/sc/sct\" URI=\"#uuid-ff9818d2-87c0-4daa-ba54-ce07e283ca38-4\" /> </o:SecurityTokenReference> <c:Offset>0</c:Offset> <c:Length>24</c:Length> <c:Nonce>zIN3JJx6Ce3YudbqTPApWQ==</c:Nonce> </c:DerivedKeyToken> <c:DerivedKeyToken u:Id=\"uuid-ce693b53-159f-492e-b79a-f904abb878d8-10\" xmlns:c=\"http://schemas.xmlsoap.org/ws/2005/02/sc\"> <o:SecurityTokenReference> <o:Reference ValueType=\"http://schemas.xmlsoap.org/ws/2005/02/sc/sct\" URI=\"#u uid-ff9818d2-87c0-4daa-ba54-ce07e283ca38-4\" /> </o:SecurityTokenReference> <c:Nonce>+ie7ja4mY4bPB5iwgiZHCg==</c:Nonce> </c:DerivedKeyToken> <e:ReferenceList xmlns:e=\"http://www.w3.org/2001/04/xmlenc#\"> <e:DataReference URI=\"#_1\" /> <e:DataReference URI=\"#_6\" /> </e:ReferenceList> <e:EncryptedData Id=\"_6\" Type=\"http://www.w3.org/2001/04/xmlenc#Element\" xmlns:e=\"http://www.w3.org/2001/04/xmlenc#\"> <e:EncryptionMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#aes256-cbc\" /> <KeyInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\"> <o:SecurityTokenReference> <o:Reference ValueType=\"http://schemas.xmlsoap.org/ws/2005/02/sc/dk\" URI=\"#uuid-ce693b53-159f-492e-b79a-f904abb878d8-10\" /> </o:SecurityTokenReference> </KeyInfo> <e:CipherData> <e:CipherValue>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</e:CipherValue> </e:CipherData> </e:EncryptedData> </o:Security> </s:Header> <s:Body u:Id=\"_0\"> <MySimpleMethod xmlns=\"http://tempuri.org/\"> <inputText>Hello</inputText> </MySimpleMethod> </s:Body> </s:Envelope>
Similar to it, if you have just changed the Binding and the address to NetTcpBinding and net:tcp://localhost:8000 it will work very similarly.
By this way you can create your own WCF service and call it from the client without even using Visual Studio.
Download Sample Code - 47KB
I hope this will help you. Thanks for reading.
I found this from google. Thanks for the post
ReplyDeleteThanks a lot, it simple open my eyes on how it really works. Could you be more specific about https autentication and ssl cerificates (more advanced form of autentication)
ReplyDeleteNice article. Was very helpful.
ReplyDelete