How can I register a WCF service programmatically within an IIS environment - wcf

Let's say we have 2 projects with following layout
Project "web"
global.asax (I thought of this destination for registration within eg void Application_Start(System.Object sender, System.EventArgs e)
web.config
Project "wcf"
DemoService.cs
IDemoService.cs
web.config would look like this
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="fooBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="wcf.DemoService"
behaviorConfiguration="fooBehavior">
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<endpoint address=""
binding="wsHttpBinding"
contract="wcf.IDemoService" />
</service>
</services>
</system.serviceModel>
</configuration>
So ... now ... somewhere (as mentioned above I thought of global.asax) I need to register, that when browsing to URI wcf.DemoServiceget's resolved and for a mex-request the wcf.IDemoService gets resolved for reading the attributes to get a WSDL.
This would usually be done by creating a .svc file and put header in the first line, e.g.:
<%# ServiceHost Language="C#" Debug="true" Service="wcf.DemoService" %>
In e.g. a console application by
var serviceHost = new ServiceHost(typeof (wcf.DemoService));
serviceHost.Open();
And combine this with a host element within the service element to specify the URI - or use another ctor-overload of ServiceHost
But I would rather go for a static registration (or any web.config registration which works for IIS 7.5) - is this possible? If so, how?

WCF 4 (.NET 4.0) offers both code based registration of services and configuration based registration of services.
Code based configuration is achieved through ASP.NET Routing by new ServiceRoute:
RouteTable.Routes.Add(new ServiceRoute("DemoService",
new ServiceHostFactory(), typeof(wcf.DemoService));
Routes are usually used with REST services but it works for SOAP services as well.
Registering service in configuration is called configuration based activation. You will define virtual .svc file in web.config:
<serviceHostingEnvironment>
<serviceActivation>
<add relativeAddress="DemoService.svc" service="wcf.DemoService" />
</serviceActivation>
</serviceHostingEnvironment>
In both cases you are defining only relative path to your service because base address is always specified by your web site hosted in IIS.

Related

"There was no endpoint listening at" issue with a IIS Hosted WCF Service consuming another web service

I have created a WCF service which is hosted in IIS and that tries to call another web service (3rd party) to return some data. When trying to connect the service fails with the following error:
There was no endpoint listening at https://xxx (3rd party ws) that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
And this is while, my service is up (i know from my echo method) and it works successfully if it is self hosted.
I have the whole and sections copied to the model of web.config exactly as it is for the self hosting test but something still is missing.
I have been through other similar problems reported but mine is little bit specific in that the service is kind-of hosting another one and that one is causing the issue.
I can try to exlain better with a real example:
There is a simple web service here: http://www.dneonline.com/calculator.asmx which I want to wrap inside our library and provide access to via an IIS hosted WCF.
So, a class library is created (Calculator project) to with one method, add to take two int arguments and use them to call the web service add method. The webservice is referenced as a Service Reference inside the library and is being addressed inside from within the config library app.config file like below:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="CalculatorSoap" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://www.dneonline.com/calculator.asmx"
binding="basicHttpBinding" bindingConfiguration="CalculatorSoap"
contract="Service.CalculatorSoap" name="CalculatorSoap" />
</client>
</system.serviceModel>
</configuration>
Then there is a WCF class library (CalcService project) which uses the first class library to enable http endpoints. Again, the app.config file includes endpoints both as for the service itself and as a client of the class library. The app.config file looks almost like this:
<configuration>
<system.serviceModel>
<services>
<service name="CalcService.Calc">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8733/Design_Time_Addresses/CalcService/Calc/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding" contract="CalcService.ICalc">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<!-- Client endpoint, i.e. to be able to use the calculator.asmx service addressed in the class library -->
<client>
<endpoint address="http://www.dneonline.com/calculator.asmx"
binding="basicHttpBinding"
contract="Service.CalculatorSoap" name="CalculatorSoap" />
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I am able to test the whole thing via a console application that makes a call to the WCF service and receives an answer. The console application config file has only one client endpoint to the WCF like below:
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/CalcService/Calc/"
binding="basicHttpBinding" contract="Calculator.ICalc" name="BasicHttpBinding_ICalc" />
</client>
</system.serviceModel>
</configuration>
My question is now how I can host the WCF service inside IIS? I have tried different ways but neither one worked. My current IIS project (which doen't work) looks like this:
1-Has project references to both prevoius projects (Class Library and WCF Service) so two dll files are being added to the references:
CalcService.dll
Calculator.dll
2-Has a CalcService.svc file which creates a ServiceHost toward the CalcService:
<%# ServiceHost Language="C#" Debug="true" Service="CalcService.Calc"%>
3-Has a web.config with cliend endpoint to calculator.asmx:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="CalculatorSoap" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://www.dneonline.com/calculator.asmx"
binding="basicHttpBinding" bindingConfiguration="CalculatorSoap"
contract="Service.CalculatorSoap" name="CalculatorSoap" />
</client>
<!-- some other settings -->
</system.serviceModel>
Now, when tested with a simple client to make a call to the calculator add method it fails with the following error:
There was no endpoint listening at http://www.dneonline.com/calculator.asmx that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
I don't know which message the endpoint is expecting, I could just assumed it has to be Service.CalculatorSoap as it worked before from the console application.
On the other hand, what confuses me is that a self hosted WCF also works (via http://localhost:8733/Design_Time_Addresses/CalcService/Calc/ from the config file in the WCF class library project).
I don't know what is missing here, is it something from the IIS configuration or permissions?
Or someting else like the windows firewall setting like explained in this post:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/bec3ab7a-310e-415f-b538-6d5681e5e53c/there-was-no-endpoint-listening-at?forum=wcf
Just note that since I am using a company computer, I'm not able to shut down the firewall. I can just turn on/off some of the rules.
I hope it is clear now what we are after.
We tested the solution on a cloud based machine and it worked fine. In the end it looked to be some firewall rules blocking the IIS outgoing calls and nothing was wrong in the configuration files or in the code.

WCF 4 Routing Multicast Configuration Frustration

I have been using stackoverflow.com as a resource as a professional programmer for years now. I would say 8 out of 10 times when I search for something on google, I get pointed to a question and answer here, and I am always relieved when that happens, because I know I am about to find the information I need.
I have been pulling my hair out trying to figure (what I think to be) a simple problem out, concerning setting up a routing service using WCF technology. I have browsed through the questions with similar titles here, and I have consulted a great many resources (both actual books on the subject, as well as websites) trying to figure this out, to no avail.
In a nutshell, I want to setup a system with the following layout:
{client}<-basicHTTP->{portal/router}<-fullWCF-WS*->{end-point-services1..n}
client: gets service reference to portal, able to call functions at end-point service
portal/router: gets requests from client, and sends them on to end-point services in a multi-cast setup
end-point-services1..n: gets request from client, routed through portal, processes request to search for things, and either responds, or logs data in a database to be checked later
I am, 100%, able to get a routing service up and running. The most successful models I have been able to follow, were outlined in the "What's new in WCF4: exercises 8 & 9, content bridging & routing" (msdn.microsoft.com/en-us/gg465212) and "Hello World with the Routing Service" (msdn.microsoft.com/en-us/library/dd795218.aspx) But I have used bits and pieces from all of the sources I have consulted (listed below).
Basically, what is frustrating me, is that I want a client (a 3rd party) to be able to just add a web service reference to the portal service (or, worst case scenario, use the svcutil.exe method), and be done with setup on their part. With that reference, they will have references to all the functions/methods they would want to call in all scenarios. The models I have looked at that do this require 2 references, one to the actual service, and one to the router, and then force the client to specifically call the router in their setup. None of my other attempts to make this particular setup work, have worked.
Your help with this would be greatly appreciated.
Here is a simplified version of my working model that almost is doing what I want:
(note, all services are being hosted in IIS)
PORTAL SERVICE (and IIS Host)
Portal.svc:
<%# ServiceHost Service="System.ServiceModel.Routing.RoutingService, System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
Web.config:
<configuration>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
...
</bindings>
<client>
<endpoint address="http://searcher1/Searcher.svc/general" binding="basicHttpBinding" contract="*" name="regularSearchServiceEndpoint" />
<endpoint address="http://searcher2/Searcher.svc/general" binding="basicHttpBinding" contract="*" name="regularSearchServiceEndpoint2" />
</client>
<behaviors>
...
</behaviors>
<routing>
<filters>
<filter name="MatchAllFilter" filterType="MatchAll" />
</filters>
<filterTables>
<filterTable name="filterTable1">
<add filterName="MatchAllFilter" endpointName="regularSearchServiceEndpoint" backupList="backupList1" priority="0"/>
</filterTable>
</filterTables>
<backupLists>
<backupList name="backupList1">
<add endpointName="regularSearchServiceEndpoint2"/>
</backupList>
</backupLists>
</routing>
<services>
<service behaviorConfiguration="routingConfiguration" name="System.ServiceModel.Routing.RoutingService">
<endpoint address="general" binding="basicHttpBinding" name="routerEndpoint1" contract="System.ServiceModel.Routing.IRequestReplyRouter" />
</service>
</services>
</system.serviceModel>
</configuration>
SEARCH SERVICE
ISearch.cs:
namespace SearchService
{
[ServiceContract]
public interface ISearch
{
[OperationContract]
string Ping();
[OperationContract]
string searchByInput(string input);
}
}
App.config:
<configuration>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<bindings>
<basicHttpBinding>
...
</basicHttpBinding>
<customBinding>
...
</customBinding>
</bindings>
<client>
...
</client>
<services>
<service name="SearchService.Search">
<endpoint address="general" binding="basicHttpBinding" contract="SearchService.ISearch" name="SearchService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/SearchService/Service1/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
SEARCH SERVICE HOST
Search.svc:
<%# ServiceHost Service="SearchService.Search" %>
Web.config:
<configuration>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<!--copied over from SearchService.App.config-->
</basicHttpBinding>
<customBinding>
<!--copied over from SearchService.App.config-->
</customBinding>
</bindings>
<client>
<!--copied over from SearchService.App.config-->
</client>
<services>
...
</services>
<behaviors>
...
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
CLIENT (where it all goes wrong)
Only way I have been able to get it to do what I want, is to add a web service reference to the searcher service (named "remotehost"), and then manually add client endpoints to the app.config file for the router, and force the client code to use that, INSTEAD of the direct link it already has to the searcher
Main.cs:
namespace Client
{
public partial class Main : Form
{
remotehost.SearchClient proxy;
public Main()
{
InitializeComponent();
proxy = new remotehost.SearchClient("RouterService");//("BasicHttpBinding_ISearch")
}
private void button1_Click(object sender,EventArgs e)
{
string response = string.Empty;
//uses method exposed by the SearchService service
response = proxy.Ping();
MessageBox.Show("Response from remote service:\n" + response
"Ping Response",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
}
App.config:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
...
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://searcher1/Searcher.svc/general" binding="basicHttpBinding" bindingConfiguration="SearchService" contract="remotehost.ISearch" name="SearchService" />
<!--I manually added this-->
<endpoint address="http://portal/Portal.svc/general" binding="basicHttpBinding" contract="remotehost.ISearch" name="RouterService" />
</client>
</system.serviceModel>
</configuration>
I want to emphasize, this all WORKS, but it doesn't work the WAY I want it to. I am fairly certain I can push/pull/cajole this into the elegant setup I am envisioning, but I can't seem to find a resource or guide that will walk me through it for the first time.
Help?
Sources I have consulted, before coming here:
Learning WCF: A Hands-on Guide, by Bustamante, Michele Leroux {978-0-5961-0162-6} (read cover to cover, and did all exercises)
Windows Communication Foundation 4: Step By Step {978-0-7356-4556-1} (focused on chapter 14: Discovering Services and Routing Messages)
msdn.microsoft.com/en-us/library/ms734712.aspx {WCF: Getting Started Tutorial}
msdn.microsoft.com/en-us/gg465212 {what's new in WCF4: exercises 8 & 9, content bridging & routing}
codeproject.com/Articles/146835/How-to-create-scalable-services-with-WCF-4-0-Route {How to create scalable services with WCF 4.0 Router and Discovery services}
msdn.microsoft.com/en-us/library/dd795218.aspx {Hello World with the Routing Service}
msdn.microsoft.com/en-us/library/ee517421.aspx {routing}
msdn.microsoft.com/en-us/library/ee517423.aspx {routing service overview}
msdn.microsoft.com/en-us/library/ee517418.aspx {routine service features}
msdn.microsoft.com/en-us/library/ee517422.aspx {routing intro}
msdn.microsoft.com/en-us/library/ee517420.aspx {routing contracts}
msdn.microsoft.com/en-us/library/bb332338.aspx {wcf routing}
msdn.microsoft.com/en-us/library/ms730158.aspx {more wcf routing}
msdn.microsoft.com/en-us/library/ee354381.aspx {more wcf routing}
dandcohen.wordpress.com/2010/03/02/wcf-4-routing-service-multicast-sample/ {WCF 4 Routing Service Multicast sample}
UPDATE: 2012-04-28:
I figured out a way to do what I wanted. It still isn't as elegant as I wanted, but it get the job done and has allowed me to move forward.
Basically, take the interface from the main service, and implement it in a new service, call it router or portal, or whatever. In the new router/portal service, add a new service reference to the main service.
Now, both services are using the same interface, and have the same signatures for all their methods, so you can then just give the portal/router service wsdl to the 3rd party client, and only allow your portal/router service to communicate with the main service.
Additionally, if you have more than one main service, you can use the portal/router service to decide which of the main services to send requests to, using multiple service references to them, and proxies to send the jobs onward. It works really well.
It is basically a manual front-end routing service, but the beauty is, the detailed work can be done in the main services on a threading model, while the gatekeeping work can be done at the portal/router, so only actual requests are sent to the main services, allowing them to only do work, and the portal services to decide how or if they get that work. The next step I want to add it automatic discovery of new services, but for now, manual configuration is working fine.
I can post the source code for what I came up with, if anyone wants to see it and requests it.
The fundamental problem is that the router knows nothing about the service contract that the service is using - it uses a universal contract (one which uses the Message type). Therefore, there is no way for the router to auto-generate the metadata for the client.
What you will need to do is provide the metadata yourself, maybe as a static WSDL document, with the correct addresses in it and point clients to this

WCF SOAP + REST/Json service without .svc - do I have twice the number of service factories?

Ok, so I wanted to have a single service exposed as a SOAP as well as REST (Json) end point. Since it's off the "WCF Service Application" template, I have a web.config and I added the following into the ...
web.config
<configuration>
...
<system.serviceModel>
<services>
<service name="MySvcClass">
<endpoint address="" binding="webHttpBinding" contract="MySvcInterfaceClass" behaviorConfiguration="restBehavior" />
<endpoint address="soap" binding="basicHttpBinding" contract="MySvcInterfaceClass" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="restBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
...
</configuration>
Assuming the MySvcClass class is implemented within \MySvcClass.svc, the above exposes ...
Original Endpoints
localhost\MySvcClass.svc\ (rest endpoint)
localhost\MySvcClass.svc\mex (Metadata Exchange to the use the SOAP end point below)
localhost\MySvcClass.svc\soap (soap endpoint)
So far, so good (I think!).
Then I wanted to get rid of the ugly ".svc" seen in the paths above. So I followed this MSDN blog post and had this in my ...
global.asax
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("MySvcClass", new WebServiceHostFactory(), typeof(MySvcClass)));
}
Interestingly, when I put a breakpoint inside Application_Start, VS2010 doesn't hit this particular breakpoint - even when I stop->start debugging or stop->start the IIS application pool. Bizarre! Anyway, back to the point, I can now access the services the above listed endpoints AND
Cleaner Endpoints
localhost\MySvcClass\ (rest endpoint)
localhost\MySvcClass\mex (Metadata Exchange to the use the SOAP end point below)
localhost\MySvcClass\soap (soap endpoint)
Questions
Am I having TWO service factories? One from the web.config and the other from the global.asax? If yes, how can I avoid it while still having clean URLs (without .svc). I don't really need the ones with .svc in the path ...
I dislike cluttered web.configs, so is there any way I can move the above SOAP and REST configuration from the XML (web.config) into code (eg global.asax?) ? I know how to move the REST only end point - wipe out in the web.config, leave global.asax as is. However doing that kills the SOAP endpoint.
[Update]
I had tried URL rewrites too but this killed the SOAP endpoint while keeping the REST endpoint alive. Wht I did was : Used MS's URL Rewrite 2.0 module with this in the web.config
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<rewrite>
<rules>
<rule name="RemoveSvcExt" stopProcessing="true">
<match url="^MySvcClass(.*)$" />
<action type="Rewrite" url="MySvcClass.svc{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
However, this leaves the web app in some inconsistent state because there are some parts which still stick to the .svc URLs. eg: the HTML help page at the service endpoint shows svcutil.exe http://localhost/MySvcClass.svc?wsdl Even the WSDL at the clean location at http://localhost/MySvcClass?wsdl makes references to http://localhost/MySvcClass.svc inside it - this effectively kills the SOAP endpoint.
That's why I think ($0.02) the rewrite is just a kludge. Sigh, at this point I'm fighting with the framework to get stuff done. And it feels such a time burner ...
For services without .svc search for file less activations in wcf
http://www.a2zdotnet.com/View.aspx?Id=188
I have a REST project that as both REST and SOAP service being exposed. Now I placed an .svc file for the SOAP service to be accessed by some clients.
The below screenshot gives the folder structure of my project, the route configuration in global.asax, Output accessing the Rest Service and accessing the .svc file (SOAP service). To remove the .svc extension use the URL rewrite module.
Please find my web.Config (My application is hosted on IIS):
Please find my class that implements my interface ISampleService:

WCF 3.5 running SOAP and REST services side by side in IIS

I know that similar question was asked here :
Running SOAP and RESTful on the same URL
Hosting WCF soap and rest endpoints side by side
but didn't find an answer to my problem.
I have two custom servicehostfactories that enables Dependency Injection :
public class StructureMapSoapServiceHostFactory : ServiceHostFactory
public class StructureMapRestServiceHostFactory : WebServiceHost2Factory
The implementation details are not important here.
Then I definied two endpoints in web.config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexGet">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<mexHttpBinding>
<binding name="mexHttpBinding" />
</mexHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="mexGet" name="ServiceImplementation.ServiceCategory">
<endpoint address="rest"
binding="webHttpBinding"
contract="Contracts.ServiceContracts.Mobile.IServiceCategory"
behaviorConfiguration ="jsonBehavior"/>
<endpoint address="soap"
binding="basicHttpBinding"
contract="Contracts.ServiceContracts.Mobile.IServiceCategory" />
<endpoint name="mexHttpBinding"
address="mex"
binding="mexHttpBinding" bindingConfiguration="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Then I created two .svc files for each custom host factories :
ServiceCategoryRest.svc
ServiceCategorySoap.svc
I don't like it. What I would like to do is to have URL in that style :
REST : http://server:port/rest/categories/{id} which mapps to the implementation of my ServiceCategory.GetCategory(int id)
SOAP : http://server:port/soap/GetCategory?id=someId
My questions are. Do i need different svc files to activate host services ? If I need there two .svc files, how can I achieve the URI above ? I'm afraid that I should configure IIS rewriting or something but would like to avoid that.
Thanks in advance for your help.
Thomas
You can achieve what you're looking for with service routes - part of ASP.NET routing, available from ASP.NET 3.5 SP1 on up.
Check out these resources:
RESTful WCF Services with No svc file and no config
Drop the Soap: WCF, REST, and Pretty URIs in .NET 4
making a WCF REST stand-alone service exe from scratch – part 1 of 4, creating the minimal bare service
Using Routes to Compose WCF WebHttp Services
In .NET 3.5 SP1, you need to add some extra infrastructure to your web.config (web routing module etc.) - while in .NET 4, this is all already built in.
After few searches I found out that in fact I don't need two different .svc files and two different ServiceHostFactories.
I kept only the StructureMapRestServiceHostFactory : WebServiceHost2Factory and ServiceCategoryRest.svc which handles well requests in REST mode and call in RPC-SOAP mode.
So if you want to run side by side the REST and the SOAP you can do it only with WebServiceHost2Factory.
If then you want to get rid of the .svc part from the URL, please read the Rick Strahl post west-wind.com/weblog/posts/570695.aspx.

Steps to host a WCF service in IIS5.1(XP)

I have developed a sample WCF service. I would like to know the steps to host this in IIS 5.1(XP)
1) You need a IIS virtual directory --> create it using IIS Manager
2) You need a *.svc file which references your service - it's a text file which must reside inside your virtual directory just created, and it would be something like:
<% #ServiceHost Service="YourNameSpace.YourServiceClass"
Language="C#" Debug="False" %>
That works if your WCF service class is in an assembly deployed to the "bin" directory below your virtual directory.
If you happen to have your actual service code in a "code-behind" file inside your "App_Code" directory (which I would not recommend), then you'd need this contents in your *.svc file:
<% #ServiceHost Service="YourServiceClass"
CodeBehind="~/App_Code/YourServiceClass.cs"
Language="C#" Debug="False" %>
3) You need your config in web.config - you need at least the <service> tag plus possibly more depending on your needs:
<system.serviceModel>
<services>
<service name="YourNameSpace.YourServiceClass"
behaviorConfiguration="MetadaTaEnabled">
<endpoint address=""
binding="wsHttpBinding"
contract="YourNameSpace.IYourService" />
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MetadaTaEnabled">
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
Here, you need to decide what binding (protocol) to use.
If you do all this, and everything was successful, you should be able to browse to your virtual directory URL with IE (http://yourserver/virtualdirectory/YourService.svc) and see the "landing page" of your service.
Marc
Have a look at this article on MSDN. It has information about hosting WCF services in all versions of IIS.