browse by category or date

WCF Service Library

WCF Service Library project will generate only the .dll file. Below is the structure of brand new WCF Service Library project:

│   App.config
│   IService1.cs
│   Service1.cs
│   WcfServiceLibrary1.csproj
│
├───bin
│   └───Debug
├───obj
│   └───Debug
│       │   .NETFramework,Version=v4.7.2.AssemblyAttributes.cs
│       │   DesignTimeResolveAssemblyReferencesInput.cache
│       │
│       └───TempPE
└───Properties
        AssemblyInfo.cs

Since it is only generating .dll, how will it be served? This is where things get interesting. We can use:

  1. IIS. We just need to create the web.config and service.svc files like a typical WCF Service Application.
    web.config
    <?xml version="1.0"?>
    <configuration>
    
      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" targetFramework="4.7.2" />
        <httpRuntime targetFramework="4.7.2"/>
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <protocolMapping>
            <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>    
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <!-- To browse web app root directory during debugging, set the value below to true.  
              Set to false before deployment to avoid disclosing web app folder information. -->      
        <directoryBrowse enabled="true"/>
      </system.webServer>
    
    </configuration>
    
    
    service.svc
    <%@ ServiceHost 
    	Language="C#" 
    	Debug="true" 
    	Service="WcfServiceLibrary1.Service1" 
    	CodeBehind="Service1.svc.cs" %>
    

    Then create a structure similar to WCF Service Application:

    │   service.svc
    │   web.config
    │
    └───bin
            WcfServiceLibrary1.dll
    
  2. Self-Hosting. Self-hosting means we will manage the program which hosts the service ourself. This means we can use any WCF transport protocol. Let’s start with a simple .NET Console program to host WCF service.
    Program.cs
    using System;
    using System.ServiceModel;
    using WcfServiceLibrary1;
    
    namespace WCFHost
    {
        class Program
        {
            static void Main(string[] args)
            { 
                using (ServiceHost host = new ServiceHost(typeof(Service1)))
                {
                    host.Open();
    
                    Console.Write("Host Open");
                    Console.ReadLine();
                    Console.WriteLine("Host closing down");
                }
            }
        }
    }
    
    App.config
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
      </startup>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior name="Service1Behavior">
              
              <serviceMetadata httpGetEnabled="true"/>
    
              
              <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
          <service name="WcfServiceLibrary1.Service1" behaviorConfiguration="Service1Behavior"> 
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:20000"/>
              </baseAddresses>
            </host> 
          </service>
    
        </services>
      </system.serviceModel>
    </configuration>
    

    Since we are hosting http other than port 80, we need to run process as Administrator, otherwise we will have this error:

    Unhandled Exception: System.ServiceModel.AddressAccessDeniedException: HTTP could not register URL http://+:20000/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details). ---> System.Net.HttpListenerException: Access is denied
       at System.Net.HttpListener.AddAllPrefixes()
       at System.Net.HttpListener.Start()
       at System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen()
       --- End of inner exception stack trace ---
       at System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen()
       at System.ServiceModel.Channels.TransportManager.Open(TransportChannelListener channelListener)
       at System.ServiceModel.Channels.TransportManagerContainer.Open(SelectTransportManagersCallback selectTransportManagerCallback)
       at System.ServiceModel.Channels.TransportChannelListener.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.HttpChannelListener`1.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
       at System.ServiceModel.Channels.CommunicationObject.Open()
       at WCFHost.Program.Main(String[] args) in D:\Projects\wcf\WCFHost\Program.cs:line 13
    

    Instead of running as Administrator everytime, we can reserve the port using the following command (must run command prompt as Administrator):

    netsh http add urlacl url=http://+:20000/ user=$MachineOrDomain\$UserName
    

    Remember to replace $MachineOrDomain and $UserName with your actual credential.

    After we run the host program, we should be able to view the service in the browser:

    We should be able to consume the service by adding service reference to the client program.

That’s it for now. Hopefully by now, we should be able to differentiate between WCF Service project, WCF Service Application project and WCF Service Library project.

I hope it helps. Cheers!

About Hardono

Howdy! I'm Hardono. I am working as a Software Developer. I am working mostly in Windows, dealing with .NET, conversing in C#. But I know a bit of Linux, mainly because I need to keep this blog operational. I've been working in Logistics/Transport industry for more than 11 years.

Possibly relevant:

WCF Service Application

This project type is a more proper ASP.NET web application project compared to WCF Service. More proper because first, it has a project file (.csproj). Second, it generates .dll files. Which means we will not include the source code when deploying the service.

Below is the structure of a brand new WCF Service Application project:

│   IService1.cs
│   Service1.svc
│   Service1.svc.cs
│   WcfServiceApplication1.csproj
│   WcfServiceApplication1.csproj.user
│   Web.config
│   Web.Debug.config
│   Web.Release.config
│
├───App_Data
├───bin
├───obj
│   └───Debug
│       │   .NETFramework,Version=v4.7.2.AssemblyAttributes.cs
│       │   DesignTimeResolveAssemblyReferencesInput.cache
│       │   WcfServiceApplication1.csproj.AssemblyReference.cache
│       │
│       └───TempPE
└───Properties
        AssemblyInfo.cs

To deploy the service, we first build the project, then publish it.

After we click Publish, Visual Studio will prompt us the publishing wizard. The wizard will first asks for the publish destination.

For flexibility, let’s choose publish to a folder. Enter the folder, then click Finish to complete the wizard.

Click the Publish button to publish the project:

Here’s how the publish output folder structure:

└───app.publish
    │   Service1.svc
    │   Web.config
    │
    └───bin
            WcfServiceApplication1.dll
            WcfServiceApplication1.pdb

Now let’s host this WCF Service Application in IIS. We can do so by creating a new Application (right-click on the Default Website, click “Add Application”)

Enter the alias, then point the physical path to the publish folder:

That’s it. The service is now accessible.

What about the Temporary ASP.NET Files? It’s slightly different compared to WCF Service website.

└───wcfapp
    └───0675c2d5
        └───d171ecc4
            │   preStartInitList.web
            │   service1.svc.cdcab7d2.compiled
            │
            ├───assembly
            │   ├───dl3
            │   │   └───3238ffdf
            │   │       └───aca18044_49c2d701
            │   │               WcfServiceApplication1.DLL
            │   │               __AssemblyInfo__.ini
            │   │
            │   ├───temp
            │   └───tmp
            └───hash
                    hash.web

Hopefully this will help us understand the difference and similarity between WCF Service and WCF Service Application project in Visual Studio. The similarity is both must served in IIS. The difference is WCF Service deploys the source code, the latter is deploying compiled binary.

Next post I will explore the most versatile among these three, WCF Service Library. Stay tuned! Cheers.

About Hardono

Howdy! I'm Hardono. I am working as a Software Developer. I am working mostly in Windows, dealing with .NET, conversing in C#. But I know a bit of Linux, mainly because I need to keep this blog operational. I've been working in Logistics/Transport industry for more than 11 years.

Possibly relevant:

WCF Service

WCF Service project type will create a ASP.NET website. Below is the folder structure of a brand new WCF Service project:

│   Service.svc
│   Web.config
│   Web.Debug.config
│
├───App_Code
│       IService.cs
│       Service.cs
│
└───App_Data

To host WCF Service, we can just create an application, then point it to the project’s folder.

How the project looks in a browser:

Whenever the service being called, .NET runtime will first check if there’s a change to the source code. If it is changed, the runtime will then compile the website. I found this out by monitoring Temporary ASP.NET Files (which is configurable from web.config):

<system.web>
	<compilation targetFramework="4.7.2" tempDirectory="D:\projects\wcf\WCFService1\WCFService1_Temp" /> 
</system.web>

Structure of Temporary ASP.NET Files (D:\projects\wcf\WCFService1\WCFService1_Temp)

└───wcfservice
    └───b4011030
        └───a40309e8
            │   App_Code.compiled
            │   App_Code.w2tcshyi.dll
            │   preStartInitList.web
            │   service.svc.cdcab7d2.compiled
            │
            ├───assembly
            │   ├───dl3
            │   ├───temp
            │   └───tmp
            └───hash
                    hash.web

Simple console program consuming the service:

D:\projects\wcf\WCFService1\WCFService1Client\bin\Debug> WCFService1Client.exe
Enter number: 123
You entered: 123
Enter number: 12355
You entered: 12355
Enter number:

To use external library, we can need to create a bin folder, then drop the .dll into it. In this experiment, I use the dll generated from Robert Greiner’s NumberText.

The folder structure after adding the .dll:

│   Service.svc
│   Web.config
│   Web.Debug.config
│
├───App_Code
│       IService.cs
│       Service.cs
│
├───App_Data
└───Bin
        NumberText.dll

I also modified Service.cs to utilize the new library:

// .. SNIP ...
using NumberText;

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service" in code, svc and config file together.
public class Service : IService
{
	public string GetData(int value)
	{
		return string.Format("You entered: {0} ( {1} ).", value, value.ToText());
		 
	}
	// .. SNIP ...
}

The result is shown in the client:

D:\projects\wcf\WCFService1\WCFService1Client\bin\Debug> WCFService1Client.exe
Enter number: 19823
You entered: 19823 ( nineteen thousand eight hundred twenty three ).
Enter number: 1982
You entered: 1982 ( one thousand nine hundred eighty two ).
Enter number: 123
You entered: 123 ( one hundred twenty three ).
Enter number: 11
You entered: 11 ( eleven ).

The updated structure of Temporary ASP.NET Files (D:\projects\wcf\WCFService1\WCFService1_Temp):

└───wcfservice
    └───b4011030
        └───a40309e8
            │   App_Code.compiled
            │   App_Code.lvuilxx9.dll
            │   preStartInitList.web
            │   service.svc.cdcab7d2.compiled
            │
            ├───assembly
            │   ├───dl3
            │   │   └───a1784ffb
            │   │       └───24224434_efc1d701
            │   │               NumberText.DLL
            │   │               __AssemblyInfo__.ini
            │   │
            │   ├───temp
            │   └───tmp
            └───hash
                    hash.web

That’s it for today. Next, I will look into WCF Service Application. Cheers!

About Hardono

Howdy! I'm Hardono. I am working as a Software Developer. I am working mostly in Windows, dealing with .NET, conversing in C#. But I know a bit of Linux, mainly because I need to keep this blog operational. I've been working in Logistics/Transport industry for more than 11 years.

Possibly relevant: