WCF Part1
What is WCF?
WCF stand for Windows comunication Foundation and is part of .NET3.0.WCF is Microsoft Platform
for building distributed and interoperable applications.
what is a distributed application ?
in simple terms a distributed application, is an application where part of it run on 2 or more computers
nodes. Distributed applications are also called as connected systems.
For example a web application running on one machine and a web service that this application is consumoing is running on another machine.
Why distributed appliations?
1. an Enterprise application may need to use the service provided by other enterprises.
for example an e-commerce application may be using Paypal service for payments.
2. for better scalability. An enterprise web application may have presentation tier, bussiness tier and data access tier, and each tier may be running on different machine.
what is an interoperable application? -> en application that can comunicate with any other application that is built on any platform is called as interoperable application.
Web services are interoperable, where as .net remotingservices are not. Web services can comunicate with any application built on any platform, where are a .net remoting service can be consumed only by another .net application.
for distributed application you can choose the following:
Enterprise Services.
dot net Remoting
Web Service (asp.net web Service only for IIS hosted)
WCF
..
In WCF (windows comunication foundation):
we can implement one service and we can configure as many endpoints as want to support all the clients needs. To support the above 2 client requirements. Also we can implement as many interface as we want with separate endpoints.We can host WCF in IIS, selft hosting (web form or console application) , service application.In IIS having WAS (windows process activation service) we can use any binding for comunications.
BINDINGS IN WCF:
WCF service endpoint consist of 3 things:
A) ADDRESS : address where the WCF service is available.
B) BINDING: the way of comunication channel will have to comunicate.
C) CONTRACT: Specifies what the service can do . for example, the service contract describes which operations the client can perform on the service.
in short, what is a binding in a WCF service?
A WCF binding defines how the client needs to comunicate with the service . The WCF binding that you choose determines the following for the comunications between the client and the serivice.
1. TRANSPORT PROTOCOL: for example tcp, http, namedpIpe, Msmq.
2. MESSAGE ENCODING: for example text/xml , binary.
3. Protocoles: for example reliable messaging, transaction support.
you can check list of bindings in https://msdn.microsoft.com/en-us/library/ms730879(v=vs.110).aspx
MESSAGE EXCHANGE PATTERNS IN WCF:
Message exchange Pattern describes how the client and the WCF service exchange message
1. request-reply (default).
2. one-way
3 duplex.
1. request reply: this is the default message exchange pattern. client send message to a wcf service and then waits for a reply. during this time the client stop processing until a response is received from the wcf service.
the client waits for call complete ven if the operation return type is void.
all WCF binding exept MSMQ based binding support the request reply message exchange pattern.
in a request reply message exchange patten faults and exceptions get resported to the client inmediatelly if any.
2. in case of one.way operation, only one message is exchanged between the client and the service . the client makes a call to the service method , but does not wait for a response message. so, in short, the receiver of the message does not send a reply message. nor does the sender
of the message expects one.
you can decorate it as [ OperationContract(IsOneWay = true)]
3. Duplex Message Exchange Pattern: can be implemented using request/reply or oneWay operations.Specify a callback contract and associate it with the service contract.
---
MESSAGE ENCONDING:
the default message encoding mechanism in WCF is Text , which base64 encodes data.This has following 2 disadvantages.
1. base64 encoding bloats the message size by approximatelly 33%.
2. involves additional processing overhad to base64 encode and decode.
the preferred approach to send large binary message in WCF is to use MTOM message encoding.
MTOM is an interoperable standard and stands for message transmission optimization mechanism. MTOM does not base64 encode data. this also means, the additional processing overhead to base64 encode and decode data is removed. hence, MTOM can significally improve the overall message transfer performance.
with Text Message encoding , the binary data is base64 encoded and it is embedded to SOAP envelop. with MTOM , binary data is included as a MIME (multipurpose internet mail extensions ) .attatchment.
To put it into practice all you have to do is change the following lines in webconfig file on bindings.
<bindings>
<wshttpBinding>
<binding name="wshttp" messageEncoding="Text"> // or MTOM
</binding>
</wshttpbinding>
</bindings>
and then add wshttp name (bindingconfiguration) to the right binding.
you can test it using Fiddler the diference of size with MTOM we can take advantage of.
--
AUTHENTICATION IN WCF
To customize the security mode for a binding use mode attribute of security element with in the respective binding.
<binding>
<nettcpbinding>
<binding name ="nettcp">
<security mode " "> -> you can choose none, transport, message, transportwithmessagecredential.
</security>...
you can check on fiddler how encript the message if only we place message mode.
we now can place below that tag, "clientCredentialType" this way:
<binding name="netTcp">
<security mode="message">
<message clientCredentialType=""/> -> can be -> none, windows, username, certificate, issuedtoken.
</security> ...
**depending the binding it will have by default its security mode and credentialtype
example: for wsHttpBinding it will be:
security mode: message
clientcredentialtype= windows.
//we can customize it.
if we hosted on IIS server we also have to set the "authentication" mode in IIS server. as an example Basic uthentication. enabled.
...
WCF Architecture:
1. soap
2.rest
WCF is a messaging framework for building distributed systems. Distributed systems is mostly just another word for web services.What this means is that you can write methods in C# (or any of the .NET languages) and then apply a bunch of configurations to the code that make your code accessible to others and turn your code into a web service.Those "bunch of configurations" are WCF. WCF allows you to expose your methods to other computers or applications using REST if you set up the WCF configurations around your C# code to expose it as a RESTful service. Or, you can easily take the same C# methods and make them available via the SOAP protocol.
If you have a method called "GetData()", you can set up the WCF configuration to make that method available in a service that is hosted in IIS. When someone calls that service, they can send an HTTP GET request to https://www.yourdomain.com/SomeService/GetData, and the GetData method will receive the message and send back a response. When you make a GET request over HTTP, you're using the REST. REST is pretty much tied to HTTP as the transport protocol. REST also has no standard message format. Whatever you want to send in your HTTP message, and however you want to send it is OK. You can send XML, or JSON, or just plain text. You can use POST, or GET or PUT or any of the HTTP verbs as well.
With SOAP, your messages can be sent to the service using any transport protocol -- you aren't tied to HTTP. SOAP messages are designed to be transport neutral. They are encoded in XML and the XML always has a head and a body node inside of an envelope node. There are lots of web standards around SOAP -- standards for putting security, sessions and other features into the header of the message, for example. Also, with SOAP, you get a WSDL, which I won't go into explaining here, but it makes it a LOT easier for clients to program against. Most programming languages have a method of taking a WSDL and converting it into strongly-typed methods and objects so that your service is easy to call.
REST is very popular on the internet and is as scalable as the internet (i.e. VERY scalable). SOAP is very popular in business-to-business applications.
for more information REST Vs Soap go here: https://msdn.microsoft.com/en-us/library/hh323708(v=vs.100).aspx
----
As an example lets develop a quick example in WCF in SOAP and consume wcf by developing a .net Client:
- Create a blank solution in Visual Studio
- Add a class library .
- add 2 class on this (one for Interface and another for Service itself)
- As we are gona host it on IIS server add new proyect as WCF site.
5. on Service.svc you should point it to the Service class
<%@ ServiceHost Language="C#" Debug="true" Service="HelloService.myservice" %>
6. let us develope the interface (Service contract):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace HelloService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "Imyservice" in both code and config file together.
[ServiceContract]
public interface Imyservice
{
[OperationContract]
string helloworld();
}
}
7. Le us implement it on Service now :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace HelloService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "myservice" in both code and config file together.
public class myservice : Imyservice
{
public string helloworld()
{
return "Hello World";
}
}
}
8. on webconfig file you can construct the system.servicemodel this way:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mxbehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<services>
<service behaviorConfiguration="mxbehavior" name="HelloService.myservice">
<endpoint address="Service" binding="basicHttpBinding" contract="HelloService.Imyservice"/>
<host>
<baseAddresses>
<add baseAddress="https://localhost:5820"/>
</baseAddresses>
</host>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
8. Now if you point to https://localhost:5820/Service.svc
you can see the Service document XML (wsdl) https://localhost:5820/Service.svc ?wsdl
9. let us créate now the client to consume Service wcf soap:
you can do it from code source dinamically, or Ajax jquery/JavaScript , or adding reference to Service reference.
- Adding Service reference
a. Add reference https://localhost:5820/Service.svc
b. on code paste this :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
ServiceReference1.ImyserviceClient myproxyservice;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
myproxyservice = new ServiceReference1.ImyserviceClient();
Label1.Text = myproxyservice.helloworld();
}
}
// so here you can see how to call Service reference and then the Service contract and its methods.
2. if you want to do it from CODE SOURCE dinamically :
you can make use of class "webclient"
using (var client = new WebClient())
{
var data = @"<?xml version=""1.0"" encoding=""utf-8""?>
<soapenv:Envelope xmlns:soapenv =""https://schemas.xmlsoap.org/soap/envelope/""
xmlns:tem =""https://tempuri.org/"">
<soapenv:Header/>
<soapenv:Body>
<tem:helloworld/>
</soapenv:Body>
</soapenv:Envelope>";
client.Headers.Add("Content-Type", "text/xml;charset=utf-8");
client.Headers.Add("SOAPAction", "\"https://tempuri.org/IMyService/MyOperation\"");
var response = client.UploadString("https://localhost:5820/Service.svc", data);
Console.WriteLine(response);
}
2. Or you can use the Http WebRequest class :
HttpWebRequest request = CreateWebRequest();
XmlDocument soapEnvelopeXml = new XmlDocument();
soapEnvelopeXml.LoadXml(@"<?xml version=""1.0"" encoding=""utf-8""?>
<soapenv:Envelope xmlns:soapenv =""https://schemas.xmlsoap.org/soap/envelope/""
xmlns:tem =""https://tempuri.org/"">
<soapenv:Header/>
<soapenv:Body>
<tem:helloworld/>
</soapenv:Body>
</soapenv:Envelope>");
using (Stream stream = request.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
using (WebResponse response = request.GetResponse())
{
using (StreamReader rd = new StreamReader(response.GetResponseStream()))
{
string soapResult = rd.ReadToEnd();
Console.WriteLine(soapResult);
}
}
}
/// <summary>
/// Create a soap webrequest to [Url]
/// </summary>
/// <returns></returns>
public HttpWebRequest CreateWebRequest()
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(@"https://localhost:5820/Service.svc");
webRequest.Headers.Add(@"SOAP:Action");
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
you can test thought fiddler or SoapUI this .Also you can make use of trace viewer and messages.
...
TRACING & MESSAGE Logging:
Use Microsoft Service configuration editor to enable tracing and message logging in WCF . This can be done either on the client or WCF Service.
- go to Tools in visual studio and then WCF Service Configuration Editor.
3. you may want to check messageLogging on and Tracing on. this appear in "diagnostic" section in the left hand panel.
also check "log auto flush" on.
4 . go to messsage Logging in "diagnostic" and place in true "EnableMessaging".
5. repro the calling to WCF Service again.
you now will see the 2 files one for tracing and another for messaging. doublé click on them to revise what you want.
If you are in production environment you will have to manually set on webconfig file the diganostics.
you can place this and modify the path and customize it as you want :
Steps for traces data collection in production environament :
1. Create a folder c:\temp
2. Give full control to everyone
3. Apply the diagnostics elements in configuration file
4. Reproduce issue
5. Comment the diagnostics elements.
===============================================================================================================================================
THIS PART WILL GO INSIDE <system.servicemodel> SECTION
=============================================================================================
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"
maxSizeOfMessageToLog="26214445" />
</diagnostics>
================================================================================================================================================
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose,ActivityTracing">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelMessageLoggingListener">
<filter type="" />
</add>
</listeners>
</source>
<source name="System.ServiceModel" switchValue="Verbose,ActivityTracing"
propagateActivity="true">
<listeners>
<add type="System.Diagnostics.DefaultTraceListener" name="Default">
<filter type="" />
</add>
<add name="ServiceModelTraceListener">
<filter type="" />
</add>
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="c:\temp\Service.messages.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelMessageLoggingListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
<filter type="" />
</add>
<add initializeData="c:\temp\Service.traces.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId, Callstack">
<filter type="" />
</add>
</sharedListeners>
</system.diagnostics>
hope this ca be useful to you. Thanks :)
Comments
- Anonymous
August 06, 2016
very detailed blog. thanks! - Anonymous
August 07, 2016
:) good!