Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

WCF Basics: Create, Host and Consume with SOAP Faults Handling

3.21/5 (5 votes)
7 Oct 2007CPOL4 min read 1   160  
An example for creating a WCF service, hosting it in a managed code application and consuming it in another application

Introduction

Before .NET Framework 3.0, Microsoft released many technologies and platforms for developing network-distributed services, including Web Services (ASMX), Web Service Enhancement (WSE), Enterprise Services (COM+), Microsoft Message Queue and (MSMQ) and Remoting. Too many technologies for a purpose lead to too many considerations when developing software systems. And it is almost impossible for switching between technologies because they have different development models.

Windows Communication Foundation (WCF) is the next-generation programming platform for building network-distributed services. It is shipped with .NET Framework 3.0 which belongs with Windows Presentation Foundation (WPF), Windows Workflow Foundation (WF) and Windows CardSpace.

WCF provides a single programming model that unifies the features of ASMX, WSE, Enterprise Services, MSMQ and Remoting. Developers now need to master one programming model only.

WCF Implementation

WCF service includes three key things that you have to do:

  • Define contracts (service contracts, operation contracts and data contracts) and implement them.
  • Define a service binding that configures the transport, security...
  • Host the service by binding the service contract to an address (endpoint)

This example implements a service that exposes a method that allows clients to register accounts with username and user's address. The username must be in capital alphabets and has at least 6 characters. The user's address is optional. After registration is successful, the client receives a profile object that has a new assigned token and user information.

This example is very simple but it demonstrates creating, SOAP Fault handling, hosting and using a WCF service.

Using the Code

Create Service Projects

Name: RegisterService
Project template: WCF Service Library

Name: RegisterServiceHost
Project template: Console Application

Define Contracts

Service Contract

  • A service contract defines a set of operations that are available on the service at endpoint and is exposed to the outside world.

  • Use ServiceContract attribute to define an interface or a class as a service contract.

Operation Contract

  • An operation contract is a method of a service contract and this method is marked as an operation contract.

  • By default, public methods of a service contract are not exposed as service operations. To make a method available at service's end-point, we mark the method with ServiceOperation attribute.

    C#
    [ServiceContract()]
    namespace DemoServices
    {
        [ServiceContract()]
        public interface IRegisterService
        {
            [OperationContract]
            [FaultContract(typeof(RegisterFault))]
            Profile Register(Profile newProfile);
        }
    }

Fault Contract

  • In managed applications, the errors are handled through Exception objects, but in SOAP applications, the errors are communicated via SOAP Faults. The exceptions at server will be converted to SOAP Faults before sending to client.

  • FaultContract attribute of a method specifies a custom SOAP Fault type for that method.

Data Contract

  • A data contract describes the data that is to be exchanged.

  • Define a data contract by marking class with DataContract attribute

Data Member

  • DataMember attribute defines which data inside a Data Contract that will be exchanged.

    C#
    namespace DemoServices
    {
        /// <summary>
        /// Represents for a user profile
        /// </summary>
        [DataContract]
        public class Profile
        {
            private string _name;
            private string _address;
            private string _token;
    
            [DataMember]
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }
            
            [DataMember]
            public string Address
            {
                get { return _address; }
                set { _address = value; }
            }
            
            [DataMember]
            public string Token
            {
                get { return _token; }
                set { _token = value; }
            }
        }
    }

Service Implementation

C#
namespace DemoServices
{
    public class RegisterService: IRegisterService
    {
        #region IRegisterService Members

        public Profile Register(Profile newProfile)
        {
            ValidateProfile(newProfile);
            newProfile.Token = Guid.NewGuid().ToString();
            return newProfile;
        }

        private static void ValidateProfile(Profile profile)
        {
            if (profile.Name.Length < 6)
            {
                throw new FaultException<registerfault>(
                    new RegisterFault(1, "Name must has at least 6 characters"));
            }

            if (!Regex.IsMatch(profile.Name, "^[A-Z]*$"))
            {
                throw new FaultException<registerfault>(
                    new RegisterFault(2, "Name must contain capital alphabets only"));
            }
        }

        #endregion
    }
}

</registerfault>

Hosting

There are many options for hosting a WCF service, including IIS, Managed code, Windows Service and WAS (Windows Process Activation Service).

For a simple demonstration, I will talk about IIS hosting and Managed code hosting (use a console application).

IIS Hosting

  • Create a Web Application (or a virtual directory).

  • Copy the output DLL of your service to the bin folder of the created Web application

  • Create a *.svc file to expose the WCF service:

    XML
    <% @ServiceHost Service="MyNamespace.MyServiceImplementationTypeName" %>
    <%@Assembly Name="MyAssemblyName" %>
    Ex: RegisterService.svc
    <% @ServiceHost Service="DemoServices.RegisterService" %>
    <%@Assembly Name="RegisterService" %>
  • Define endpoint for the service in web.config

    XML
    <system.serviceModel>
      <services>
        <service name="DemoServices.RegisterService"
                 behaviorConfiguration="RegisterServiceBehavior">
          <endpoint address="RegisterService"
                    binding="basicHttpBinding"
                    contract="DemoServices.IRegisterService" />
        </service>
      </services>
      <behaviors>
          <behavior name="RegisterServiceBehavior">
            <serviceMetadata httpGetEnabled="true" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
    

    Now, you can add Service Reference to your application. The service URL should be:

    [your web application url][/your virtual directory]/RegisterService.svc

Managed Code Application Hosting

The limitation of hosting WCF service on IIS is that the communication allows HTTP only. For other protocols, such as TCP, namepipe…, we need to host WCF services in managed code applications, Windows services or WAS.

In this article, I used a console application for hosting the Register service.
This is the application configuration file of the console app. It says that we will host the service with TCP protocol and allow clients to use metadata exchange for generating service proxy.

XML
<system.serviceModel>
  <services>
    <service name="DemoServices.RegisterService"
             behaviorConfiguration="RegisterServiceBehavior">
      <endpoint address="net.tcp://localhost:12347/RegisterService"
                binding="netTcpBinding"
                contract="DemoServices.IRegisterService" />

      <endpoint address="http://localhost:12348/RegisterService/mex"
                binding="mexHttpBinding"
                contract="IMetadataExchange" />
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="RegisterServiceBehavior">
        <serviceDebug includeExceptionDetailInFaults="True"/>
        <serviceMetadata/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

After completing the above steps, run your host application to make the service active.

Consume Service

  • Create a console application

  • Add Service Reference to your project, the service URI should be: http://localhost:12348/RegisterService/mex as configured above and give it a name, such as WCFRegisterService.

Add this sample code to consume the Register service with custom SOAP Fault handling:

C#
static void Main(string[] args)
{
	WCFRegisterService.RegisterServiceClient client = 
		new WCFRegisterService.RegisterServiceClient();
	WCFRegisterService.Profile newProfile = new WCFRegisterService.Profile();
	newProfile.Name = "MYNAME";
	newProfile.Address = "My Address";

	WCFRegisterService.Profile result;

	try
	{
		result = client.Register(newProfile);
		Console.WriteLine("New token: {0}", result.Token);
		client.Close();
	}
	catch (FaultException<WCFRegisterService.registerfault> fault)
	{
		Console.WriteLine("Register error code: {0}", fault.Detail.ErrorCode);
		Console.WriteLine
			("Register error message: {0}", fault.Detail.Message);
		client.Abort();
	}
	catch(Exception ex)
	{
		Console.WriteLine("General exception: {0}", ex.Message);
		client.Abort();
	}
	Console.ReadLine();
} 

Points of Interest

As you can see, it's quite easy to develop a service oriented application with WCF. Developers need to learn about WCF only and they can develop and host their services in many ways without changing their code.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)