Академический Документы
Профессиональный Документы
Культура Документы
This article will help you to understand WCF Service Architecture. It describes major components of
WCF like Contracts and its different types, Policies and Binding, Service Runtime, Messaging,
Activation and Hosting and how they work together.
WCF service is collection of Endpoints and each endpoint describes how service is going to be
communicate with clients. Endpoint has Address which tells where the WCF service
resides, Bindings describes which protocol will be used for communication and Contract which
gives details about how data will be exchanged.
Below diagram from MSDN describes you how WCF application works.
Components of WCF
Contracts
Basically WCF contracts defines how service behaves and what opeartions it
exposes to clients. If service execution get some exception then service might
issue fault and contract decides what kind of fault to issue. Contracts also
defines What kind of MEPs required by service?
Below are WCF Contract Types
Service Runtime
It describes different behavior that can make effect on service run time. After
you design and implement ServiceContracts you can configure service and
operation behavior. Using those behaviors you can achieve through puts,
reliability and performance of services. Below are WCF behaviors which can
be configured in configuration file or programmatically.
Instance Behavior: decides how objects are created and refers to the
life time of the service object. Whenever clients make request runtime will
create service objects to provide the response. Through instancing we can
control how long this service instance wants to be retained. By setting
InstanceContextMode property of ServiceBehavior you can control
instance behavior. You can set it as PerCall, PerSession or Single.
Messaging
WCF messaging provides a unified programing model and flexibility for
presenting data and messages exchanges. Messaging layer has many channels,
those channels are called as Channel Stack. Each channel involves in some or
other way in processing of message like authentication, sending or recieving
messages to and from endpoint. Channels are included in
System.ServiceModel.Channels namespace.
There are two types of channels
IIS: you can host only HTTP/HTTPs based WCF services in if your
using IIS 6.0 or previous versions. Hosting in IIS gives feature like
"activation on demand" your service code is not in memory for all time
and gets instantiated whenever first request comes in.
See how to host WCF service in IIS
WAS: is the new process activation method that comes with IIS 7.0.
You can host WCF service and have HTTP and non HTTP (TCP or
netNamedPipe protocols) based message based activation
Message exchange patterns are standard design which tells how the communication between WCF
service and client should happen. It decides protocols for communication channels to exchange
messages between service and clients and help interoperability.
WCF supports three message exchange patterns which are described below.
1. One Way
One Way mep is like short term memory loss, it just fires the execution
and forget about the response. It is useful when client do not require the
response back like changing status of order, logging some noncritical
operations. If you are using MSMQ bindings then One way mep is the best
choice for communication as client just needs to call the queue and
execution of task is totally depend on queue. For marking the operation as
one way use IsOneWay = True.
[ServiceContract]
public interface IOrders
{
[OperationContract(IsOneWay=true)]
public void CompleteOrder(int orderID);
}
2. Request-response
In Request-response mep client sends message to WCF service and service
sends back some response with required processing. This is the most used
pattern in SOA as many real time operation requires some status or data
back as response. Using this pattern with the void return type operations
empty SOAP body will be send to client as response. For marking
operation as Request-response you do not have do anything as the default
property of IsOneWay is false.
[ServiceContract]
public interface IOrders
{
[OperationContract]
public void PlaceOrder(Order order);
}
3. Duplex
Duplex pattern is two way message channel where service and client can
communicate independently with each other and execute operations.
Client should provide the appropriate endpoint using it service should be
able to send messages. In real time application Duplex pattern is
complicated as it service required active connection and open firewalls of
client which is usually avoided because of security. Most of the Duplex
contracts requires long running sessions at cost of performance.
[ServiceContract]
public interface IOrderDuplexCallback
{
[OperationContract(IsOneWay = true)]
void ShowShipmentDetails(Delivery delivery);
}
[ServiceContract(Namespace = "http://NorthwindServices/OrderService",
SessionMode=SessionMode.PerSession,
CallbackContract=typeof(IOrderDuplexCallback))]
public interface IOrder
{
[OperationContract(IsOneWay = true)]
void PlaceOrder(Order order);
}
The difference between Request-response and Duplex pattern is, Requestresponse pattern requires the response on same communication channel
whereas Duplex will create the separate communication channel to return
response to client.
[ServiceContract(Namespace = "http://NorthwindServices/OrderService",
SessionMode=SessionMode.Allowed,
CallbackContract=typeof(IOrderDuplexCallback))]
public interface IOrder
{
[OperationContract(IsOneWay = true)]
void PlaceOrder(Order order);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class OrderService : IOrder
{
public void PlaceOrder(int orderID)
{
//Add code for placing orders
/// <summar>
/// Read only public property to give access to callback contract
/// </summary>
public IOrderDuplexCallback Callback
{
get
{
return OperationContext.Current.GetCallbackChannel
<IOrderDuplexCallback>();
}
}
}
<services>
<service name="NorthwindServices.OrderService">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:7741/NorthwindServices
/OrderService/" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsDualHttpBinding"
contract="NorthwindServices.IOrder">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
5. Host OrderService
Host this OrderService as suggested in Hosting WCF service in
IIS. orhosting in Windows service.
6. Client Application
Add the client application as suggested in article for Hosting service in
previous step.
using Northwind.OrderServiceRef;
Open the program.cs from client console application and add below code.
It creates the InstanceContext of callback and hit the service operation.
[ServiceContract(Name="Product")]
public interface IProductService
{
2. CallbackContract
Callback contracts are used in duplex message channel where client and
server can call each other. (Read more on WCF MEP) In duplex model
client send request to server it might be time consuming operation and
then service needs to provide notification to client through callback
contracts. If you use callbackcontract you will loose the service
interoperability. Also you need to consider that not all bindings support
callback contracts like the bindings which are depend on HTTP protocols.
HTTP protocols are stateless whereas duplex channel require live
connection to complete the operation.
[ServiceContract]
interface IOrdersCallback
{
[OperationContract(IsOneWay = true)]
void OnOrderPlaced(string message, DateTime timestamp);
}
[ServiceContract(CallbackContract = typeof(IOrdersCallback))]
public interface IOrders
{
[OperationContract]
bool OrderPlace(Order order);
}
3. ConfigurationName
By using ConfigurationName property you can set the service name in
service config file. It specifies the name of config element for service.
[ServiceContract(Name="Orders", ConfigurationName="OrderService")]
public interface IOrders
{
[OperationContract]
void PlaceOrder(Order order);
}
In config file
<service name="OrderService">
<endpoint
address="http://localhost:8080/OrderService" binding="basicHttpBinding"
bindingConfiguration="myBindingConfiguration" contract="IOrders">
</service>
4. HasProtectionLevel
It is a read only boolean property. If the ProtectionLevel property is set to
other than "None", HasProtectionLevel property will return true else
return false.
5. ProtectionLevel
It allows you to define protection level for all messages on wire. There are
three different options of ProtectionLevel enum available.
o
[ServiceContract(ProtectionLevel = ProtectionLevel.Sign)]
public interface IOrderService
{
[OperationContract()]
bool PlaceOrder();
}
6. Namespace
If you are having multiple services with similar method signatures adding
a unique namespace value to service contract will help you as your
methods will become unique by using this feature. This property is very
important while serialization and deserialization as you might have
similar class names at client side and service side.
[ServiceContract(Namespace="http://northwind.com/orderservice") ]
public interface IOrderService
{
[OperationContract(Name="GetOrder")]
Order GetOrder(int orderID);
}
7. SessionMode
It allows you to decide how session should work for your service. Only
bindings with WS-*, NetTcpBinding and NetNamedPipeBinding allows
sessions. There are three ways to handle sessions.
o
[ServiceContract(SessionMode = SessionMode.Allowed)]
[ServiceContract()]
public interface IOrders
{
[OperationContract(Name="PlaceOrder")]
bool OrderPlace(Order order);
}
[ServiceContract(Namespace="http://orders.northwind.com")]
public interface IOrders
{
[OperationContract(
Action="http://orders.northwind.com/placeorders",
Name="PlaceOrders",
ReplyAction="http://orders.northwind.com/reorderqty"
)]
Message PlaceOrders(Message msg);
}
3. AsyncPattern
AsyncPattern is a Boolean property with default value of false. You can
mark it as true if your service operation should execute asynchronously on
client or server or both. You should create the asynchronous operations to
handle long running processes like I/O calls.
[ServiceContract]
public interface IOrders
{
[OperationContract]
int TodaysOrderCount(DateTime dt);
[OperationContract(AsyncPattern = true)]
IAsyncResult BeginPlaceOrder(Order order, AsyncCallback cb, Object state);
4. HasProtectionLevel
HasProtectionLevel is a read only Boolean property with default value of
false. If value of ProtectionLevel is set to "None" it will return false and if
ProtectionLevel is set to Sign or EncryptAndSign it will return true.
5. IsInitiating
IsInitiating is a Boolean property with default value of false. The service
operation marked with IsInitiating = true must be called before any other
operation from client side. This operation will create new session for
client. For use of this the ServiceContract should support sessions by
marking SessionMode=SessionMode.Required or
SessionMode=SessionMode.Allowed. This property can be used where
Service Contract needs to validate the client details before executing any
operation.
From below example client must call ValidateClient before any other
operation call. If any other operation get called before ValidateClient
service returns ActionNotSupported FaultException. Operation
PlaceOrder can be call many times after calling ValidateClient and before
CloseChannel.
[ServiceContract(SessionMode=SessionMode.Required)]
public class OrderService
{
[OperationContract(
IsOneWay=true,
IsInitiating=true,
IsTerminating=false
)]
public void ValidateClient()
{
return true;
}
[OperationContract(
IsInitiating=false,
IsTerminating=false
)]
public bool PlaceOrder(Order order)
{
// Place order code
return true;
}
[OperationContract(
IsOneWay=true,
IsInitiating=false,
IsTerminating=true
)]
public void CloseChannel()
{
//code to end session for current client
}
}
6. IsTerminating
This is a Boolean property with default value of false. IsTerminating is
used to close client's current session. In previous example once operation
CloseChannel called no other calls can be made to service except
ValidateClient.
7. IsOneWay
IsOneWay is Boolean property with default value of false. For making
operation as One way you need to set IsOneWay = true. IsOneWay
operations has short term memory loss, it just fired and forget without
bothering about response or execution of operation.
Sometime operation just need to execute without expecting the response
like marking the order status. You cannot use FaultException,
TransactionContext with OneWay operations. If you are using MSMQ
bindings One Way operations are very much useful. If the value of
IsOneWay is false and operation's return type is void then empty SOAP
body return.
[ServiceContract]
public interface IOrders
{
[OperationContract(IsOneWay=true)]
public void ChangeOrderStatus(int orderID, OrderStatus orderStatus);
}
8. Name
Name is string property with default value of Operation Name. It allows
you to give operation name with more meaningful value than the default
method name. This value will be generated in WSDL for <Operation>
element.
[ServiceContract]
public interface IOrders
{
[OperationContract(Name="GetOrderReport")]
String OrderReport(DateTime dt);
}
9. ProtectionLevel
The default value for ProtectionLevel is None or the value which is set at
ServiceContract level. It defines the Protection Level of operation and how
service messages will be protected. The value for ProtectionLevel can be
set as
o
o
o
[ServiceContract()]
WCF DataContracts
This article explains required steps to implement WCF DataContracts with Enum members.
DataContract represents the business entities like Product, Customer, Order. It is a agreement
between service and clients for exchanging data.
Go through an article on WCF DataContract attributes for the best use of DataContracts.
using System.Runtime.Serialization;
namespace NorthwindServices
{
[DataContract]
public enum ProductWebOnly
{
[EnumMember]
Yes,
[EnumMember]
No
}
}
3. Product datastore
Create or replace Products.xml for service data store. Add below xml to
the file.
Note that XML is different than the one created in first step. Added
newWebOnly element for ProductWebOnly enum
<Products>
<ProductID>1</ProductID>
<ProductName>Chai</ProductName>
<categoryID>1</categoryID>
<UnitsInStock>39</UnitsInStock>
<CategoryName>Condiments</CategoryName>
<WebOnly>Yes</WebOnly>
</Products>
<Products>
<ProductID>2</ProductID>
<ProductName>Chang</ProductName>
<categoryID>1</categoryID>
<UnitsInStock>17</UnitsInStock>
<CategoryName>Condiments</CategoryName>
<WebOnly>No</WebOnly>
</Products>
<Products>
<ProductID>3</ProductID>
<ProductName>Aniseed Syrup</ProductName>
<categoryID>2</categoryID>
<UnitsInStock>13</UnitsInStock>
<CategoryName>Condiments</CategoryName>
<WebOnly>Yes</WebOnly>
</Products>
</DocumentElement>
using System.Runtime.Serialization;
namespace NorthwindServices
{
[DataContract]
public class Product
{
[DataMember]
public int ProductID { get; set; }
[DataMember]
public string ProductName { get; set; }
[DataMember]
public int CategoryID { get; set; }
[DataMember]
public string CategoryName { get; set; }
[DataMember]
public int UnitsInStock { get; set; }
[DataMember]
public ProductWebOnly WebOnly { get; set; }
}
}
5.
New OperationContract
using System.ServiceModel;
namespace NorthwindServices
{
[ServiceContract]
public interface IProducts
{
[OperationContract]
string GetProductName(int productID);
[OperationContract]
int GetProductQty(int productID);
[OperationContract]
string GetCategoryName(int productID);
[OperationContract]
List<Product> GetAllProducts();
[OperationContract]
bool AddProduct(Product product);
}
}
using System.Xml.Linq;
namespace NorthwindServices
{
public class ProductService : IProducts
{
public Product GetProduct(int productID)
{
Product product = new Product();
IEnumerable<XElement> products =
(from result in doc.Descendants("DocumentElement")
.Descendants("Products")
where result.Element("ProductID").Value==productID.ToString()
select result);
product.ProductID =
products.ElementAt(0).Element("ProductID").Value;
product.ProductName =
products.ElementAt(0).Element("ProductName").Value;
product.CategoryID =
products.ElementAt(0).Element("categoryID").Value;
product.UnitsInStock =
products.ElementAt(0).Element("UnitsInStock").Value;
product.WebOnly =
(ProductWebOnly)Enum.Parse(typeof(ProductWebOnly),
products.ElementAt(0).Element("WebOnly").Value);
return product;
}
IEnumerable<XElement> products =
(from result in doc.Descendants("DocumentElement")
.Descendants("Products")
select result);
product.ProductID = element.Element("ProductID").Value;
product.ProductName = element.Element("ProductName").Value;
product.CategoryID = element.Element("categoryID").Value;
product.UnitsInStock = element.Element("UnitsInStock").Value;
product.WebOnly=(ProductWebOnly)Enum.Parse(
typeof(ProductWebOnly), element.Element("WebOnly").Value);
lstProducts.Add(product);
}
return lstProducts;
}
doc.Element("DocumentElement").Add(
new XElement("Products",
new XElement("ProductID", product.ProductID),
new XElement("ProductName", product.ProductName),
new XElement("UnitsInStock", product.UnitsInStock),
new XElement("CategoryID", product.CategoryID),
new XElement("CategoryName", product.CategoryName),
new XElement("WebOnly", product.WebOnly)));
doc.Save("C:\\products.xml");
return true;
}
}
}
7. ProductService Endpoint
You do not need to change anything from app.config file for service
endpoint as you have just added some methods to ServiceContract and
do not have change address, binding or contract.
Make sure you have below endpoint in app.config of Service library.
<service name="NorthwindServices.ProductService">
<host>
<baseAddresses>
<add baseAddress =
"http://localhost:7741/NorthwindServices/ProductService" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsHttpBinding"
contract="NorthwindServices.IProducts">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
using NorthwindApp.ProductServiceRef;
namespace NorthwindApp
{
class Program
{
static void Main(string[] args)
{
AddProduct();
GetAllProducts();
GetProductDetails();
Console.Read();
}
{
Product[] products = client.GetAllProducts();
Implementation of MessageContract
Below is an implementation of MessageContract where Northwind WCF
service has heterogeneous client ask for the customer info. Only clients with
specific license key will get the required response else WCF FaultExceptionwill
be thrown.
2. Customer DataContract
Add new Customer DataContract to handle the Customer related info by
adding new class to Service library. Add below code to the class and
reference to System.Runtime.Serialization
namespace NorthwindServices
{
[DataContract]
public class Customer
{
[DataMember]
public string CustomerName;
[DataMember]
public string PhoneNumber;
[DataMember]
public string Email;
}
}
3. Request MessageContract
Create a new MessageContract for request by adding new class to Service
library. Name it as CustomerContactRequest. Add reference to
System.ServiceModel
namespace NorthwindServices
{
[MessageContract(IsWrapped=false)]
public class CustomerContactRequest
{
[MessageHeader]
public string LicenseKey;
[MessageBodyMember]
public int CustomerID;
}
}
4. Response MessageContract
Create a MessageContract for response.
namespace NorthwindServices
{
[MessageContract(IsWrapped = false)]
public class CustomerContactResponse
{
[MessageBodyMember]
public Customer Contact;
}
}
5. Add ServiceContract
Add a service contract to handle customer message request and response.
[ServiceContract]
public class ICustomerService
{
[OperationContract]
[FaultContract(typeof(string)]
CustomerContactResponse
GetCustomerContact(CustomerContactRequest request);
}
6. Implementation of ICustomerService
Implement ICustomerService as below. If LicenseKey is matching return
the contact information else throw FaultException.
/// </summary>
public CustomerContactResponse
GetCustomerContact(CustomerContactRequest request)
{
if (request.LicenseKey != AppKey)
throw new FaultException<string>("Invalid Key");
<service name="NorthwindServices.CustomerService">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:7741/NorthwindServices/
CustomerService" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsHttpBinding"
contract="NorthwindServices.ICustomerService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
8. Host CustomerService
Host the CustomerService in hosting WCF service in IIS or in hosting in
Windows service.
9. CustomerService client
Add client application for WCF CustomerService as suggested by article in
previous. step.
Add ServiceReference to CustomerService to NorthwindApp client
application by right clicking on Service References -> Enter
http://localhost:7741/NorthwindServices/CustomerService in address
box and click Go.
Add a reference to NorthwindApp.CustomerServiceRef in Program.cs
Add below client code in Program.cs of client application.
response.Contact = client.GetCustomerContact
("northwind-xxx-1234-abc", 1234);
Console.WriteLine(response.Contact.CustomerName);
Console.WriteLine(response.Contact.Email);
Console.WriteLine(response.Contact.PhoneNumber);
}
catch (FaultException<string> ex)
{
Console.WriteLine(ex.Detail);
}
Console.Read();
}
2.
3.
[DataContract]
public class ServiceException
{
/// <summary>
/// <summary>
/// If critical, user should redirect to error page
/// and exception details should log.
/// </summary>
[DataMember]
public bool IsCritical { get; set; }
}
3. Exception Manager
Add new sealed class to project and name it as ExceptionManager. This
class will work as single point to handle all WCF service exceptions and
errors.
return exception;
}
return exception;
}
/// <summary>
/// If error is not user defined then IsCritical should be true.
/// </summary>
/// <param name="ex">Exception</param>
/// <returns>bool value</returns>
private static bool IsCritical(System.Exception ex)
{
4. Add FaultContracts
Add FaultContracts to OperationContract.
[ServiceContract]
public interface IProducts
{
[OperationContract]
[FaultContract(typeof(ServiceException))]
string GetProductName(int productID);
[OperationContract]
[FaultContract(typeof(ServiceException))]
int GetProductQty(int productID);
[OperationContract]
[FaultContract(typeof(ServiceException))]
5. FaultContract Implementation
Add implementation for FaultContract. If any error occurs, error will be
handled by ExceptionManager class and custom message will be return to
clients.
try
{
XDocument doc = XDocument.Load("products.xml");
productName =
(from result in doc.Descendants("DocumentElement")
.Descendants("Products")
where result.Element("productID").Value == productID.ToString()
select result.Element("productname").Value)
.FirstOrDefault<string>();
if (string.IsNullOrEmpty(productName))
throw new FaultException<ServiceException>(ExceptionManager.
HandleException("Product ID does not exist in system."));
}catch (Exception ex)
{
return productName;
}
try
{
XDocument doc = XDocument.Load("products.xml");
string strProductQty =
(from result in doc.Descendants("DocumentElement")
.Descendants("Products")
where result.Element("productID").Value == productID.ToString()
select result.Element("UnitsInStock").Value)
.FirstOrDefault<string>();
if (string.IsNullOrEmpty(strProductQty))
throw new FaultException<ServiceException>(ExceptionManager.
HandleException("Product ID does not exist in system."));
categoryName =
(from result in doc.Descendants("DocumentElement")
.Descendants("Products")
where result.Element("productID").Value == productID.ToString()
select result.Element("CategoryName").Value)
.FirstOrDefault<string>();
if (string.IsNullOrEmpty(categoryName))
throw new FaultException<ServiceException>(ExceptionManager.
HandleException("Product ID does not exist in system."));
}catch (Exception ex)
{
throw new FaultException<ServiceException>
(ExceptionManager.HandleException(ex));
}
return categoryName;
}
}
6. Hosting Service
Host this WCF service in IIS or in Windows service.
9. Client Implementation
Service reference is now available for Northwind. We can call service
operations and implement error handling using FaultContracts. Add the
below code to NorthwindApp -> Program.cs file.
class Program
{
static void Main(string[] args)
{
ShowOperations();
}
do
{
Console.WriteLine();
Console.WriteLine("Enter Product ID or press Esc to quit : ");
cki = Console.ReadKey();
if (!char.IsNumber(cki.KeyChar))
{
Console.WriteLine(" Invalid number");
}
else
{
Int32 number;
if (Int32.TryParse(cki.KeyChar.ToString(), out number))
{
Console.WriteLine();
GetProductName(number);
GetProductQty(number);
GetCategoryName(number);
}
else
{
Console.WriteLine("Unable to parse input");
}
}
} while (cki.Key != ConsoleKey.Escape);
Console.Read();
}
Protocols: specifies what type of security can be used like reliable messaging or transaction
context.
2.
3.
2. WsHttpBinding
This is secure and interoperable bindings uses SOAP over HTTP. With
WsHttpBinding messages are encrypted by default and achieve message
level security. It supports reliability, transactions and security over
internet. It supports HTTP or HTTPS protocols and text as well as MTOM
encoding.
The difference between basicHttpBinding and WsHttpBindingis
WsHttpBinding does support WS-* standards like WS-Addressing, WSSecurity and WS-ReliableMessaging
3. wsDualHttpBinding
wsDualHttpBinding is best when you required bidirectional
communication with client. In some scenario when client makes call to
WCF service, after processing of long running request service has to call
client application for example updating shipment details to client
application.
It supports reliability, transactions and security over internet. It supports
HTTP or HTTPS protocols and text as well as MTOM encoding. You can
implement Duplex message exchange pattern with wsDualHttpBinding.
4. webHttpBinding
webHttpBinding is best when you wish to implement RESTful WCF
service. This is secure and interoperable binding which sends information
directly over HTTP or HTTPS without creating SOAP messages. It allows
HTTP request to use plain old XML (POX) style messaging which reduces
the message size on wire compare to SOAP messages.
5. NetTcpBinding
netTcpBinding is best when WCF service and its clients are in intranet
infrastructure. As it supports only TCP protocol and not HTTP so service
cannot be accessed over internet.
This is secure binding is used to send binary encoded SOAP messages with
in intranet computers. It supports reliability, transaction and security. If
your using netTcpBinding and host WCF service in IIS, you need to make
some settings on system and IIS this article will help you for required
settings.
6. netNamedPipeBinding
When your WCF service and its clients reside on same computer
netNamedPipeBinding is the best choice and gives best performance over
other bindings. This is secure bindings. Binary encoded SOAP messages
are sent over named pipes.
See how to implement netNamedPipeBinding in WCF services.
7. netPeerTcpBinding
netPeerTcpBinding is best when you require more security for peer to peer
communication as netTcpBinding does not provide it. It is secure binding
and supports TCP protocols.
8. WsFederationHttpBinding
It is secure and interoperable binding supports federated security. It
supports HTTP and HTTPS transport protocols as well as text and MTOM
encodings.
9. NetMsmqBinding
netMsmqBinding is best when you have to execute service operations in
queued manner. Service requests are placed in queue and executed one by
one. With netMsmqBinding service operations will always be one way and
does not return any response to client.
This is interoperable bindings and can be used on existing MSMQ
applications that use COM or Application Programing Interface(API)
In real time applications you have to use multiple bindings for one service
endpoints. For example internet applications should be able to access service
through HTTP request at same time the back office application should be able
to access service by netTcpBinding or netNamedPipeBinding to get
performance benefits.
CategoryName,ProductID));
}
catch(FaultException<ServiceException> ex)
{
Console.WriteLine(string.Format("Errors
occured in service : {0} ", ex.Detail.Message));
}
}
}
If you are hosting WCF service in IIS you can use IIS infrastructure to
set up SSL.
<system.serviceModel>
<services>
<service name="NorthwindServices.ProductService">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="NorthwindServices.IProducts"/>
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
namespace NorthwindClient
{
class Program
{
static void Main(string[] args)
{
ProductServiceRef.ProductsClient client
= new ProductServiceRef.ProductsClient();
string category = client.GetCategoryName(1);
string name = client.GetProductName(1);
int qty = client.GetProductQty(1);
Console.WriteLine("Product Name : " + name);
Console.WriteLine("Product Qty : " + qty.ToString());
Console.WriteLine("Product Category : " + category);
Console.Read();
}
}
}
https://localhost/ProductServiceHost.svc
Change it to
https://<your computer name>/ProductServiceHost.svc
WCF Security
WCF provides three modes for security. Transport, Message and
TransportWithMessageCredential. Transport security can be achieved with SSL over http(https).
This article elaborates Message Level security. TransportWithMessageCredential is a
combination of other two.
<system.serviceModel>
<services>
<service name="NorthwindServices.ProductService"
behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress =
"http://localhost:7741/NorthwindServices
/ProductService/" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsHttpBinding"
contract="NorthwindServices.IProducts"
bindingConfiguration ="wsMessage">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior" >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name ="wsMessage">
<security mode ="Message">
<message clientCredentialType ="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
clientCredentialType
clientCredentialType can have any value from below available options for
Message Level Security.
1. None: Messages are secured with encryption however it does not
perform any authentication.
2. Windows: Messages are secured with encryption and clients are
authenticated using built in Windows Authentication which can be
through Active Directory or NTLM.
3. UserName: Messages are secured and encrypted and clients are
authenticated by provided UserName and Password.
4. Certificate: Messages are encrypted and both service and clients are
authenticated with certificates.
5. IssuedToken: Messages are encrypted and authentication happens
through issued tokens by authority like Cardspace.
Client Application
Create a new console application as client for this WCF service. Add service
reference of ProductService to client application.
using NorthwindApp.ProductServiceRef;
namespace NorthwindApp
{
class Program
{
static void Main(string[] args)
{
ProductsClient client = new ProductsClient();
string cateName = client.GetCategoryName(1);
Console.WriteLine(cateName);
Console.Read();
}
}
}
Enable WCF Tracing and Message Logging for client application to see how
communication has encrypted. Execute application and open SvcTraceViewer.
SvcTraceViewer is located at C:\Program Files (x86)\Microsoft
SDKs\Windows\v7.0A\Bin. If you do not have SvcTraceViewer
installed click here to download.
Trace and Messages must have generated after execution of client application.
Open it and notice how messages are encrypted.
WCF supports three message exchange patterns which are described below.
1. One Way
One Way mep is like short term memory loss, it just fires the execution
and forget about the response. It is useful when client do not require the
response back like changing status of order, logging some noncritical
operations. If you are using MSMQ bindings then One way mep is the best
choice for communication as client just needs to call the queue and
execution of task is totally depend on queue. For marking the operation as
one way use IsOneWay = True.
[ServiceContract]
public interface IOrders
{
[OperationContract(IsOneWay=true)]
public void CompleteOrder(int orderID);
}
2. Request-response
In Request-response mep client sends message to WCF service and service
sends back some response with required processing. This is the most used
pattern in SOA as many real time operation requires some status or data
back as response. Using this pattern with the void return type operations
empty SOAP body will be send to client as response. For marking
operation as Request-response you do not have do anything as the default
property of IsOneWay is false.
[ServiceContract]
public interface IOrders
{
[OperationContract]
public void PlaceOrder(Order order);
}
3. Duplex
Duplex pattern is two way message channel where service and client can
communicate independently with each other and execute operations.
Client should provide the appropriate endpoint using it service should be
able to send messages. In real time application Duplex pattern is
complicated as it service required active connection and open firewalls of
client which is usually avoided because of security. Most of the Duplex
contracts requires long running sessions at cost of performance.
[ServiceContract]
public interface IOrderDuplexCallback
{
[OperationContract(IsOneWay = true)]
void ShowShipmentDetails(Delivery delivery);
}
[ServiceContract(Namespace = "http://NorthwindServices/OrderService",
SessionMode=SessionMode.PerSession,
CallbackContract=typeof(IOrderDuplexCallback))]
public interface IOrder
{
[OperationContract(IsOneWay = true)]
void PlaceOrder(Order order);
}
The difference between Request-response and Duplex pattern is, Requestresponse pattern requires the response on same communication channel
whereas Duplex will create the separate communication channel to return
response to client.
[ServiceContract(Namespace = "http://NorthwindServices/OrderService",
SessionMode=SessionMode.Allowed,
CallbackContract=typeof(IOrderDuplexCallback))]
public interface IOrder
{
[OperationContract(IsOneWay = true)]
void PlaceOrder(Order order);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class OrderService : IOrder
{
public void PlaceOrder(int orderID)
{
//Add code for placing orders
/// <summar>
/// Read only public property to give access to callback contract
/// </summary>
public IOrderDuplexCallback Callback
{
get
{
return OperationContext.Current.GetCallbackChannel
<IOrderDuplexCallback>();
}
}
}
<services>
<service name="NorthwindServices.OrderService">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:7741/NorthwindServices
/OrderService/" />
</baseAddresses>
</host>
<endpoint address ="" binding="wsDualHttpBinding"
contract="NorthwindServices.IOrder">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
5. Host OrderService
Host this OrderService as suggested in Hosting WCF service in
IIS. orhosting in Windows service.
6. Client Application
Add the client application as suggested in article for Hosting service in
previous step.
using Northwind.OrderServiceRef;
Client Code
int i = 0;
DateTime n = DateTime.Now;
Console.WriteLine(i.ToString());
namespace NorthwindServices
{
[ServiceContract]
public interface ICustomer
{
}
}
3. Add OperationContracts
Add a reference to System.ServiceModel. Add OperationContract for
Customer Service. The operation contract GetCustomerName and
GetCustomerCount can be called by service clients.
namespace NorthwindServices
{
[ServiceContract]
public interface ICustomer
{
[OperationContract]
string GetCustomerName(int CustomerID);
[OperationContract]
int GetCustomerCount();
}
}
4. Customer DataAccess
We will use an XML file as Customer data store. Create a new XML and
add below elements to it.
</Customer>
<Customer>
<CustomerID>5</CustomerID>
<CompanyName>Kountry Store</CompanyName>
<City>Pune</City>
</Customer>
</DocumentElement>
namespace NorthwindServices
{
public class CustomerService : ICustomer
{
public string GetCustomerName(int CustomerID)
{
XDocument doc = XDocument.Load("C:\\Customers.xml");
string companyName =
(from result in doc.Descendants("DocumentElement")
.Descendants("Customer")
where result.Element("CustomerID").Value
== CustomerID.ToString()
select result.Element("CompanyName").Value)
.FirstOrDefault<string>();
return companyName;
}
return doc.Descendants("Customer").Count();
}
}
}
6. Service Endpoint
Open NorthwindServices wcf service library's app.config file. Add service
endpoint for customer service under <system.serviceModel><services>
tag.
Note that the address we are using is with net.pipe://localhost/
If you are using only one endpoint with netNamedPipeBinding for service
mark the httpGetEnabled as false from respective serviceBehaviors.
<system.serviceModel>
<services>
<service
name="NorthwindServices.CustomerService"
behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/NorthwindServices/" />
</baseAddresses>
</host>
<endpoint address="CustomerService"
binding="netNamedPipeBinding"
contract="NorthwindServices.ICustomer" />
<endpoint address="CustomerService/mex"
binding="mexNamedPipeBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="False" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
So you will have to add host for CustomerService and its endpoint details
in Windows service application as there are for ProductService. Add the
endpoint with net.pipe://localhost/ just like you added in
NorthwindServices.
9. Execute CustomerService
Write below code in client application to execute Service operations.
class Program
{
static void Main(string[] args)
{
int customerID = 2;
CustomerClient client = new CustomerClient();
string companyName = client.GetCustomerName(2);
Console.WriteLine(string.Format("Company name for Customer ID {0} is {1}",
customerID, companyName));
Console.WriteLine(string.Format("Total number of customers are {0} : ",
client.GetCustomerCount()));
Console.Read();
}
}
>
Quick Note : While using code from this article make sure you mention the
right path for Customers.xml
with different endpoint and bindings. And also tells you how to host these services in IIS 7+ or in
Windows Services.
For this tutorial we will create two WCF services as 1.CustomerService and
2.OrderService
2. Northwind Solution
Create empty solution by opening Visual Studio and click on File menu ->
Project -> Click on Other Project Types from Installed Template -> Select
Blank Solution
Give a name as Northwind.
4. Service Contracts
1.
2.
3.
4.
5.
using System.ServiceModel;
6.
7.
namespace NorthwindServices.ServiceContracts
8.
9.
[ServiceContract(Namespace =
"http://dotnetmentors.com/services/customer")]
10.
11.
12.
[OperationContract]
13.
14.
15.
[OperationContract]
16.
17.
18.
[OperationContract]
19.
int GetCustomerCount();
20.
21.
using System.ServiceModel;
namespace NorthwindServices.ServiceContracts
{
[ServiceContract(Namespace = "http://dotnetmentors.com/services/order")]
[OperationContract]
string GetOrderAmount(int OrderID);
[OperationContract]
string GetShipCountry(int orderID);
}
}
5. Datastore
Add two new XML files name it as Customers.xml and Orders.xml. These
xml files will be used as datastore for OrderService and CustomerService
respectively.
Customers.xml
Orders.xml
<OrderDate>1996-07-08</OrderDate>
<ShippedDate>1996-07-15</ShippedDate>
<ShipCountry>France</ShipCountry>
<OrderTotal>1057</OrderTotal>
</Orders>
</DocumentElement>
2.
3.
4.
using NorthwindServices.ServiceContracts;
5.
using System.Xml.Linq;
6.
7.
namespace NorthwindServices.Services
8.
9.
[ServiceBehavior(Namespace="http://dotnetmentors.com/services/customer")]
10.
11.
12.
13.
14.
15.
16.
string companyName =
17.
18.
.Descendants("Customer")
19.
where result.Element("CustomerID").Value
20.
== CustomerID.ToString()
21.
select result.Element("CompanyName").Value)
22.
.FirstOrDefault<string>();
23.
24.
return companyName;
25.
26.
27.
28.
29.
30.
31.
string companyName =
32.
33.
.Descendants("Customer")
34.
where result.Element("CustomerID").Value
35.
== CustomerID.ToString()
36.
select result.Element("City").Value)
37.
.FirstOrDefault<string>();
38.
39.
return companyName;
40.
41.
42.
43.
44.
45.
46.
return doc.Descendants("Customer").Count();
47.
48.
49.
}
}
using NorthwindServices.ServiceContracts;
53.
using System.Xml.Linq;
54.
55.
namespace NorthwindServices.Services
56.
57.
[ServiceBehavior(Namespace="http://dotnetmentors.com/services/order")]
58.
59.
60.
61.
62.
63.
64.
string orderDate =
65.
66.
.Descendants("Orders")
67.
where result.Element("OrderID").Value
68.
== orderID.ToString()
69.
select result.Element("OrderDate").Value)
70.
.FirstOrDefault<string>();
71.
72.
73.
return orderDate;
}
74.
75.
76.
77.
78.
79.
80.
string orderTotal =
(from result in doc.Descendants("DocumentElement")
81.
.Descendants("Orders")
82.
where result.Element("OrderID").Value
83.
== orderID.ToString()
84.
select result.Element("OrderTotal").Value)
85.
.FirstOrDefault<string>();
86.
87.
return orderTotal;
88.
89.
90.
91.
92.
93.
94.
string shipCountry =
95.
96.
.Descendants("Orders")
97.
where result.Element("OrderID").Value
98.
== orderID.ToString()
99.
select result.Element("ShipCountry").Value)
100.
.FirstOrDefault<string>();
101.
102.
return shipCountry;
103.
104.
}
}
105. }
7. Service Endpoint
Add Service Endpoints for CustomerService and OrderService.
<system.serviceModel>
<services>
<service name="NorthwindServices.Services.CustomerService"
behaviorConfiguration ="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7741/NorthwindServices/Services
/CustomerService" />
<add baseAddress="net.pipe://localhost/Services/CustomerService" />
</baseAddresses>
</host>
</service>
<service name="NorthwindServices.Services.OrderService"
behaviorConfiguration ="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7741/NorthwindServices/Services
/OrderService" />
<add baseAddress="net.pipe://localhost/Services/OrderService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name ="ServiceBehavior" >
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
2.
2.
3.
net.pipe://localhost/Services/CustomerService
4.
5.
net.pipe://localhost/Services/OrderService
6.
When you add service you will have client endpoint in your console
applications app.config. You will have both netNamedPipeBinding
and wsHttpBinding endpoint in your client app.config.
Add below code to client application
using NorthwindBackOffice.CustomerServiceRef;
using NorthwindBackOffice.OrderServiceRef;
namespace NorthwindBackOffice
{
class Program
{
static void Main(string[] args)
{
ShowCustomerDetails();
Console.WriteLine();
ShowOrderDetails();
Console.Read();
}
8.
9.
10.
http://localhost:7741/NorthwindServices/Services/OrderService
For creating and hosting WCF service in IIS follow below steps.
3. ServiceHost tag
Add below service host tag to ProductServiceHost.svc. Give fully qualified
name of service to ServiceHost attribute.
o
o
5. Publish Services
Go to your service application and right click on service project and select
publish.
9. Client Implementation
Service reference is now available for Northwind. We can call service
operations. Add the below code to NorthwindApp -> Program.cs file.
class Program
{
static void Main(string[] args)
{
ShowOperations();
}
do
{
Console.WriteLine();
Console.WriteLine("Enter Product ID or press Esc to quit : ");
cki = Console.ReadKey();
if (!char.IsNumber(cki.KeyChar))
{
Console.WriteLine(" Invalid number");
}
else
{
Int32 number;
if (Int32.TryParse(cki.KeyChar.ToString(), out number))
{
Console.WriteLine();
GetProductName(number);
GetProductQty(number);
GetCategoryName(number);
}
else
{
Console.WriteLine("Unable to parse input");
}
}
} while (cki.Key != ConsoleKey.Escape);
Console.Read();
}
See more details about Hosting WCF service in IIS with SSL and Transport
Security
Download source code
1.
Service will be automatically start whenever the hosting computer start. Service can be
manually start, stop or restart.
2.
Service will always be activated and available for clients. No need for runtime activation.
3.
4.
5.
6.
namespace NorthwindHost
{
internal class ProductServiceHost
{
static ServiceHost serviceHost = null;
public ProductServiceHost()
{
namespace NorthwindHost
{
public partial class ServiceHosts : ServiceBase
{
public ServiceHosts()
{
InitializeComponent();
ServiceName = "Northwind Services";
}
5. Run ServiceHosts
Open Program.cs from NorthwindHost windows service application and
run the ServiceHosts.
namespace NorthwindHost
{
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new ServiceHosts()
};
ServiceBase.Run(ServicesToRun);
}
}
}
6. Add Installer
Add Installer class to NorthwindHost windows service application by right
click on NorthwindHost -> select Add -> New Item -> select Installer.cs
from Visual C# templates.
Name the newly created Installer.cs as NorthwindInstaller.cs
Right click NorthwindInstaller from solution explorer and select view
code.
Add reference to System.ServiceProcess and add below code to
NorthwindInstaller constructor.
namespace NorthwindHost
{
[RunInstaller(true)]
public partial class ProjectInstaller
: System.Configuration.Install.Installer
{
private ServiceProcessInstaller process;
private ServiceInstaller service;
public ProjectInstaller()
{
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();
service.StartType = ServiceStartMode.Automatic;
service.ServiceName = "Northwind Servces";
service.Description = "Northwind Servces";
Installers.Add(process);
Installers.Add(service);
}
}
}
7. Config settings
Copy <system.serviceModel> settings from your NorthwindServices WCF
service and paste it in NorthwindHost windows service's app.config file
under <configuration> tag.
With this your service is ready for install.
[ServiceBehavior(Name = "ProductService",
Namespace = "http://dotnetmentors.com/productservice",
InstanceContextMode = InstanceContextMode.PerSession)]
ProductServiceRef.ProductServiceClient client
= new ProductServiceRef.ProductServiceClient();
It creates a new client proxy for Product Service. WCF service will create new
dedicated instance to handle this proxy. The data which is manipulated by this
instace will be saved in memory for future reference. All request will be handle
by this instance untill you call client.close();
client.SetProductQty(10);
Console.WriteLine(string.Format
("Current Product Qty: {0}", client.GetProductQty()));
client.SetProductQty(20);
Console.WriteLine(string.Format
("Current Product Qty: {0}", client.GetProductQty()));
Console.WriteLine(string.Format
("Current Product Qty: {0}", client.GetProductQty()));
client.Close();
Now you assign new service instance to client object and call operation
contract to read value of ProductQty however you haven't set the value and
previous proxy is closed you will be getting value as 0(integer default).
Your entire code block will look like this.
namespace ClientApp
{
class Program
{
client.SetProductQty(10);
Console.WriteLine(string.Format
("Current Product Qty: {0}", client.GetProductQty()));
client.SetProductQty(20);
Console.WriteLine(string.Format
("Current Product Qty: {0}", client.GetProductQty()));
Console.WriteLine(string.Format
("Current Product Qty: {0}", client.GetProductQty()));
client.Close();
Console.Read();
}
}
}
This article helps you to understand how per call wcf service works and how its instances get created.
This article will also go through a tutorial for implementing and notice execution of Per Call WCF
Service.
PerCall services are highly scalable. Server crash affects to only current
ongoing instance and its execution, next calls will be routed to another
server.
using System.ServiceModel;
namespace PerCallService
{
[ServiceContract(Name = "ProductService",
Namespace = "http://northwind.com/productservice")]
public interface IProductService
{
[OperationContract]
void SetProductQty(int qty);
[OperationContract]
int GetProductQty();
}
}
using System.ServiceModel;
namespace PerCallService
{
[ServiceBehavior(Name = "ProductService",
Namespace = "http://northwind.com/productservice",
InstanceContextMode= InstanceContextMode.PerCall)]
public class ProductService : IProductService
{
public void SetProductQty(int qty)
{
this.ProductQty = qty;
}
We added one private property ProductQty which is used for reading and
writing value for ProductQty.
We implemented OperationContract SetProductQty which set value of
ProductQty given by service client.
We implemented OperationContract GetProductQty which returns value of
ProductQty.
In ServiceBehavior attribute we marked service as PerCall.
<service name="PerCallService.ProductService">
<host>
<baseAddresses>
<add baseAddress =
"http://localhost:7741/PerCallService/ProductService" />
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding"
contract="PerCallService.IProductService"
bindingNamespace ="http://northwind.com/productservice" >
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
[ServiceBehavior(Name = "ProductService",
Namespace = "http://northwind.com/productservice")]
public class ProductService :
IProductService
{
// implementation of operation contract.
}
Build service, publish it again, update service reference for client application
and execute client application. You will see the ProductQty as 10. As service is
PerSession, service maintain object state for multiple calls made from same
proxy.
ChannelFactory
Proxy
ChannelFactory
CategoryServiceClient
In shared assembly we have CategoryService contract which we will
implement using ChannelFactory.
Add new class to NorthwindClient console application and name it
asCategoryServiceClient.
CategoryService has two method
1. GetCategoryName which returns category name based on given category
ID. Below is implementation of this GetCategoryName.
categoryName = instance.GetCategoryName(categoryID);
myChannelFactory.Close();
return categoryName;
}
category = instance.GetCategoryDetails(categoryID);
myChannelFactory.Close();
return category;
}
We assume that you have created a WCF service and hosted in IIS as
suggested in first step. In this step we create a declartive endpoint to
CategoryServiceHost.
ChannelFactory<ICategoryService> creates new instance of
CategoryService and ChannelFactory.CreateChannel() returns instance
using which we can call service operations dynamically.
using NorthwindContracts.DataContracts;
using NorthwindContracts.ServiceContracts;
namespace NorthwindClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(CategoryServiceClient.GetCategoryName(10));
Category category =
CategoryServiceClient.GetCategoryDetails(10);
if (category != null)
{
Console.WriteLine("Category ID " + category.CategoryID);
Console.WriteLine("Category Name: "
+ category.CategoryName);
Console.WriteLine("Category Description:"
+ category.CategoryDescription);
}
Console.Read();
}
}
}
[DataMember]
public string CategoryURL { get; set; }
return category;
}
WCF Tracing:
WCF tracing enables you to diagnose data, fault messages and its analysis. Tracing is better option
than debugging to understand the application's behavior and its flow. Tracing gives you the details of
all application components like fault and code exceptions, system events, operation calls. Depending
on the Switch Value traces will be generated.
WCF tracing is not enabled by default you need to configure it with the switch
value and tracelistener.
Switch Value: Switch value decides what level of trace needs to be
generated. Below default values are available for Switch Value
1.
2.
3.
4.
5.
6.
7.
8.
Trace Listener: WCF services and clients add trace data to listeners
configured app.config file. There are couple of predefined trace listeners like
XmlWriterTraceListener which can be used to save trace.
TheinitializeData property must be set to some physical file.
3. Configure Tracing
Open the app.config file of WCF service library and add the configuration
for system.diagnostics.
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Critical,Information,ActivityTracing"
propagateActivity="true">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\logs\messages.svclog" />
</listeners>
</source>
</sources>
<trace autoflush="true" />
</system.diagnostics>
4. Use of TraceViewer
Execute some of the service operations using client application. The file
messages.svclog must have created under C:\logs folder. Open the file by
using SvcTraceViewer.exe.
2.
3.
4.
5.
6.
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\logs\northwindservices.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="false"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="false"
maxMessagesToLog="500"
maxSizeOfMessageToLog="5000"/>
</diagnostics>
</system.serviceModel>