Four Ways:
- Adding Service Reference
- Using Tool i.e. SvcUtil.exe
- Implementing ClientBase
- Implement Channel Factory
#1:Adding Service Reference
- Easy/Simple Way to Implement
- Internal creates proxy by adding Service Reference
- Help: http://www.topwcftutorials.net/2014/05/calling-wcf-self-hosted-console-application.html
#2: Using Tool i.e. SvcUtil.exe
- Again Easy/Simple Way to Implement
- Host Service
- Run svctool to generate proxy - svcutil http://localhost:4321/StudentService /out:StudentServiceProxy.cs
- Add newly created proxy class to our client application “ClientApp3″.
- Then call WCF Service using proxy class.
- Help: https://www.codeproject.com/Articles/786601/Ways-to-generate-proxy-for-WCF-Service
#3:Implementing ClientBase
- Generating proxy by using ClientBase class option has an advantage
- That it creates proxy at run time, so it will accommodate service implementation changes
- public class StudentServiceProxy : ClientBase, IStudentService
{
public string GetStudentInfo(int studentId)
{
return base.Channel.GetStudentInfo(studentId);
}
}
- Help: https://www.codeproject.com/Articles/786601/Ways-to-generate-proxy-for-WCF-Service
#4: Implement Channel Factory
- No Need to create proxy here. I.e. Channel Factory enables you to create a communication channel to the service without a proxy.
- Cases where service is tightly bound with to the client application, we can use an interface DLL directly and with the help of a Channel Factory.
- Channel Factory class is useful when you want to share a common service contract DLL between the client and the server.
- ChannelFactory takes a generic parameter of the service type (it must be a service contract interface) to create a channel.
- Because ChannelFactory only requires knowledge of the service contract, it makes good design sense to put service/data contracts in separate assemblies from service implementations.
- This way, you can safely distribute contract assemblies to third parties who wish to consume services, without the risk of disclosing their actual implementation.
- Code:
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://localhost:3047/Service1.svc");
ChannelFactory myChannelFactory = new ChannelFactory(myBinding, myEndpoint);
IService1 instance = myChannelFactory.CreateChannel();
// Call Service.
Console.WriteLine(instance.GetData(10));
myChannelFactory.Close();
- Help:
- https://www.c-sharpcorner.com/UploadFile/ff2f08/channel-factory-in-wcf/
- https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-channelfactory
Fault Exception:
Throw Fault Exception: Three Ways
namespace HelloIndigo.Lab4.Fault
{
[ServiceContract(Namespace = "http://www.thatindigogirl.com/samples/2006/06")]
public interface IHelloIndigoService
{
[OperationContract]
[FaultContract(typeof(InvalidOperationException))]
void ThrowSimpleFault();
[OperationContract()]
[FaultContract(typeof(InvalidOperationException))]
void ThrowFaultException();
[OperationContract]
[FaultContract(typeof(InvalidOperationException))]
void ThrowMessageFault();
}
[ServiceBehavior(IncludeExceptionDetailInFaults=false)]
public class HelloIndigoService : IHelloIndigoService
{
public void ThrowSimpleFault()
{
throw new FaultException(new FaultReason("Invalid operation."));
}
public void ThrowFaultException()
{
FaultException<InvalidOperationException> fe = new FaultException <InvalidOperationException> (
new InvalidOperationException("An invalid operation has occured."),
new FaultReason("Invalid operation."),
new FaultCode("Server", new FaultCode(String.Format("Server.{0}", typeof(NotImplementedException)))));
throw fe;
}
public void ThrowMessageFault()
{
InvalidOperationException error = new InvalidOperationException("An invalid operation has occurred.");
MessageFault mfault = MessageFault.CreateFault(
new FaultCode("Server", new FaultCode(String.Format("Server.{0}", error.GetType().Name))),
new FaultReason("Invalid operation."),
error);
FaultException fe = FaultException.CreateFault(mfault, typeof(InvalidOperationException));
throw fe;
}
}
}
Catch Fault Exception:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using HelloIndigoClient.HIServiceReferenceFault;
namespace HelloIndigoClient
{
class Program
{
static void Main(string[] args)
{
HelloIndigoServiceClient proxy = new HelloIndigoServiceClient();
try
{
proxy.ThrowSimpleFault();
}
catch (FaultException fe)
{
Console.WriteLine(fe.GetType().ToString());
Console.WriteLine("ERROR: {0}", fe.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().ToString());
Console.WriteLine("Normal ERROR: {0}", ex.Message);
}
// -----------------------------------------------------------------
try
{
proxy.ThrowFaultException();
}
catch (FaultException<InvalidOperationException> fe)
{
Console.WriteLine(fe.GetType().ToString());
Console.WriteLine("ERROR: {0}", fe.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().ToString());
Console.WriteLine("Normal ERROR: {0}", ex.Message);
}
Console.WriteLine();
// -----------------------------------------------------------------
try
{
proxy.ThrowMessageFault();
}
catch (FaultException fe)
{
Console.WriteLine(fe.GetType().ToString());
Console.WriteLine("ERROR: {0}", fe.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().ToString());
Console.WriteLine("Normal ERROR: {0}", ex.Message);
}
proxy.Close();
}
}
}
Catch Fault Exception : In Correct Order
Because FaultException<TDetail> derives from FaultException, and FaultException derives from CommunicationException, it is important to catch these exceptions in the proper order. If, for example, you have a try/catch block in which you first catch CommunicationException, all specified and unspecified SOAP faults are handled there; any subsequent catch blocks to handle a custom FaultException<TDetail> exception are never invoked.
Remember that one operation can return any number of specified faults. Each fault is a unique type and must be handled separately.
Note:
CommunicationException class has two important derived types,
FaultException exceptions are thrown when a listener receives a fault that is not expected or not specified in the operation contract. Usually this occurs when the application is being debugged and the service has the ServiceDebugBehavior.IncludeExceptionDetailInFaults property set to true.
FaultException exceptions are thrown on the client when a fault that is specified in the operation contract is received in response to a two-way operation (that is, a method with an OperationContractAttribute attribute with IsOneWay set to false).
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;
public class Client
{
public static void Main()
{
// Picks up configuration from the config file.
SampleServiceClient wcfClient = new SampleServiceClient();
try
{
// Making calls.
Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));
wcfClient.Close();
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException<GreetingFault> greetingFault)
{
Console.WriteLine(greetingFault.Detail.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException unknownFault)
{
Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
Console.ReadLine();
wcfClient.Abort();
}
}
}
Throttling:
Throttling is mainly derived from the throughput keyword. Throughput means that the work performs or can be performed in a given specific time interval.
The throughput of any WCF Service mainly depends on three things:
To control such factors we have to use throttling. In throttling, you can specify it in two ways: In app.config or At hosting time programmatically.
Config File:
<behaviors>
<serviceBehaviors>
<behavior name="throttlingBehavior">
<serviceThrottling
maxConcurrentCalls="2"
maxConcurrentInstances="2"
maxConcurrentSessions="2"/>
</behavior>
</serviceBehaviors>
</behaviors>
Programmatically
ServiceHost host = new ServiceHost(typeof(ThrottlingInWCF.ThrottlingInWCF));
ServiceThrottlingBehavior stb= new ServiceThrottlingBehavior();
stb.MaxConcurrentCalls=2;
stb.MaxConcurrentInstances=2;
stb.MaxConcurrentSessions=2;
host.Description.Behaviors.Add(stb);
host.Open();
Console.Write("Service started...");
Console.Read();
Hope this helps...
Regards,
Arun Manglick
- Adding Service Reference
- Using Tool i.e. SvcUtil.exe
- Implementing ClientBase
- Implement Channel Factory
#1:Adding Service Reference
- Easy/Simple Way to Implement
- Internal creates proxy by adding Service Reference
- Help: http://www.topwcftutorials.net/2014/05/calling-wcf-self-hosted-console-application.html
#2: Using Tool i.e. SvcUtil.exe
- Again Easy/Simple Way to Implement
- Host Service
- Run svctool to generate proxy - svcutil http://localhost:4321/StudentService /out:StudentServiceProxy.cs
- Add newly created proxy class to our client application “ClientApp3″.
- Then call WCF Service using proxy class.
- Help: https://www.codeproject.com/Articles/786601/Ways-to-generate-proxy-for-WCF-Service
#3:Implementing ClientBase
- Generating proxy by using ClientBase
- That it creates proxy at run time, so it will accommodate service implementation changes
- public class StudentServiceProxy : ClientBase
{
public string GetStudentInfo(int studentId)
{
return base.Channel.GetStudentInfo(studentId);
}
}
- Help: https://www.codeproject.com/Articles/786601/Ways-to-generate-proxy-for-WCF-Service
#4: Implement Channel Factory
- No Need to create proxy here. I.e. Channel Factory enables you to create a communication channel to the service without a proxy.
- Cases where service is tightly bound with to the client application, we can use an interface DLL directly and with the help of a Channel Factory.
- Channel Factory class is useful when you want to share a common service contract DLL between the client and the server.
- ChannelFactory
- Because ChannelFactory only requires knowledge of the service contract, it makes good design sense to put service/data contracts in separate assemblies from service implementations.
- This way, you can safely distribute contract assemblies to third parties who wish to consume services, without the risk of disclosing their actual implementation.
- Code:
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://localhost:3047/Service1.svc");
ChannelFactory
IService1 instance = myChannelFactory.CreateChannel();
// Call Service.
Console.WriteLine(instance.GetData(10));
myChannelFactory.Close();
- Help:
- https://www.c-sharpcorner.com/UploadFile/ff2f08/channel-factory-in-wcf/
- https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-use-the-channelfactory
Fault Exception:
Throw Fault Exception: Three Ways
namespace HelloIndigo.Lab4.Fault
{
[ServiceContract(Namespace = "http://www.thatindigogirl.com/samples/2006/06")]
public interface IHelloIndigoService
{
[OperationContract]
[FaultContract(typeof(InvalidOperationException))]
void ThrowSimpleFault();
[OperationContract()]
[FaultContract(typeof(InvalidOperationException))]
void ThrowFaultException();
[OperationContract]
[FaultContract(typeof(InvalidOperationException))]
void ThrowMessageFault();
}
[ServiceBehavior(IncludeExceptionDetailInFaults=false)]
public class HelloIndigoService : IHelloIndigoService
{
public void ThrowSimpleFault()
{
throw new FaultException(new FaultReason("Invalid operation."));
}
public void ThrowFaultException()
{
FaultException<InvalidOperationException>
new InvalidOperationException("An invalid operation has occured."),
new FaultReason("Invalid operation."),
new FaultCode("Server", new FaultCode(String.Format("Server.{0}", typeof(NotImplementedException)))));
throw fe;
}
public void ThrowMessageFault()
{
InvalidOperationException error = new InvalidOperationException("An invalid operation has occurred.");
MessageFault mfault = MessageFault.CreateFault(
new FaultCode("Server", new FaultCode(String.Format("Server.{0}", error.GetType().Name))),
new FaultReason("Invalid operation."),
error);
FaultException fe = FaultException.CreateFault(mfault, typeof(InvalidOperationException));
throw fe;
}
}
}
Catch Fault Exception:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using HelloIndigoClient.HIServiceReferenceFault;
namespace HelloIndigoClient
{
class Program
{
static void Main(string[] args)
{
HelloIndigoServiceClient proxy = new HelloIndigoServiceClient();
try
{
proxy.ThrowSimpleFault();
}
catch (FaultException fe)
{
Console.WriteLine(fe.GetType().ToString());
Console.WriteLine("ERROR: {0}", fe.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().ToString());
Console.WriteLine("Normal ERROR: {0}", ex.Message);
}
// -----------------------------------------------------------------
try
{
proxy.ThrowFaultException();
}
catch (FaultException<InvalidOperationException> fe)
{
Console.WriteLine(fe.GetType().ToString());
Console.WriteLine("ERROR: {0}", fe.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().ToString());
Console.WriteLine("Normal ERROR: {0}", ex.Message);
}
Console.WriteLine();
// -----------------------------------------------------------------
try
{
proxy.ThrowMessageFault();
}
catch (FaultException fe)
{
Console.WriteLine(fe.GetType().ToString());
Console.WriteLine("ERROR: {0}", fe.Message);
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().ToString());
Console.WriteLine("Normal ERROR: {0}", ex.Message);
}
proxy.Close();
}
}
}
Because FaultException<TDetail> derives from FaultException, and FaultException derives from CommunicationException, it is important to catch these exceptions in the proper order. If, for example, you have a try/catch block in which you first catch CommunicationException, all specified and unspecified SOAP faults are handled there; any subsequent catch blocks to handle a custom FaultException<TDetail> exception are never invoked.
Remember that one operation can return any number of specified faults. Each fault is a unique type and must be handled separately.
Note:
CommunicationException class has two important derived types,
- FaultException and
- Generic FaultException
type.
FaultException exceptions are thrown when a listener receives a fault that is not expected or not specified in the operation contract. Usually this occurs when the application is being debugged and the service has the ServiceDebugBehavior.IncludeExceptionDetailInFaults property set to true.
FaultException
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.WCF.Documentation;
public class Client
{
public static void Main()
{
// Picks up configuration from the config file.
SampleServiceClient wcfClient = new SampleServiceClient();
try
{
// Making calls.
Console.WriteLine("The service responded: " + wcfClient.SampleMethod(greeting));
wcfClient.Close();
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException<GreetingFault> greetingFault)
{
Console.WriteLine(greetingFault.Detail.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (FaultException unknownFault)
{
Console.WriteLine("An unknown exception was received. " + unknownFault.Message);
Console.ReadLine();
wcfClient.Abort();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message + commProblem.StackTrace);
Console.ReadLine();
wcfClient.Abort();
}
}
}
Throttling:
Throttling is mainly derived from the throughput keyword. Throughput means that the work performs or can be performed in a given specific time interval.
The throughput of any WCF Service mainly depends on three things:
- maxConcurrentCalls - Controls client can create a maximum number of 2 concurrent calls to communicate with WCF Service
- maxConcurrentInstances - Controls client can create a maximum number of 2 concurrent instances to communicate with WCF Service
- maxConcurrentSessions - Controls client can create a maximum number of 2 concurrent sessions to communicate with WCF Service
To control such factors we have to use throttling. In throttling, you can specify it in two ways: In app.config or At hosting time programmatically.
<behaviors>
<serviceBehaviors>
<behavior name="throttlingBehavior">
<serviceThrottling
maxConcurrentCalls="2"
maxConcurrentInstances="2"
maxConcurrentSessions="2"/>
</behavior>
</serviceBehaviors>
</behaviors>
Programmatically
ServiceHost host = new ServiceHost(typeof(ThrottlingInWCF.ThrottlingInWCF));
ServiceThrottlingBehavior stb= new ServiceThrottlingBehavior();
stb.MaxConcurrentCalls=2;
stb.MaxConcurrentInstances=2;
stb.MaxConcurrentSessions=2;
host.Description.Behaviors.Add(stb);
host.Open();
Console.Write("Service started...");
Console.Read();
Hope this helps...
Regards,
Arun Manglick