Cannot access WCF url hosted as a windows service - c#

I have created a WCFLibrary which has :
[OperationContract]
string TestCall();
And my app.config has this :
<endpoint address="" binding="wsHttpBinding" contract="TestWCF.ITestService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/TestWCF/TestService/" />
</baseAddresses>
</host>
My Windowsservice has this :
protected override void OnStart(string[] args)
{
host = new ServiceHost(typeof(TestWCF.TestService));
}
Have compiled exe and installed it as a service everything is fine till this point.
Now I wanted to check this url from browser :
*http://localhost:8732/Design_Time_Addresses/TestWCF/TestService*
but due to some reasons I cant make a call to my WCF hosted in Windows Service, What might be went wrong am I missing anything ?

protected override void OnStart(string[] args)
{
host = new ServiceHost(typeof(TestWCF.TestService));
host.Open(); // :-)
}

Related

Can't access WCF service after versioning service contracts

I'm having trouble figuring out an issue with a WCF service that has appeared after I have implemented a "v2" contract to it to extend functionality. Everything builds fine but when I try to access the service in the browser I just get told that it cannot connect. When I try to add it as a service reference I get a similar message regarding connection issues. However, when I remove the extended contract's endpoint from the config file, and leave the previous "v1" version intact, it works fine.
Here is the "v1" contract:
namespace Company.Services.Ticketing.Retail.Contracts
{
[ServiceContract(Name = "OutletReportingContract_v1", Namespace = "https://enterprise.company.ie/Services/Retail")]
public interface IOutletReportingContract_v1
{
/* methods */
}
}
And here is the "v2" contract:
namespace Company.Services.Ticketing.Retail.Contracts
{
[ServiceContract(Name = "OutletReportingContract_v2", Namespace = "https://enterprise.company.ie/Services/Retail")]
public interface IOutletReportingContract_v2 : IOutletReportingContract_v1
{
/* methods */
}
}
Here are the endpoints in the Web.config:
<service name="Company.Services.Ticketing.Retail.OutletService" behaviorConfiguration="Public">
<endpoint address="1" binding="wsHttpBinding" bindingConfiguration="Standard" name="OutletReportingContract_v1"
contract="Company.Services.Ticketing.Retail.Contracts.IOutletReportingContract_v1" />
<endpoint address="2" binding="wsHttpBinding" bindingConfiguration="Standard" name="OutletReportingContract_v2"
contract="Company.Services.Ticketing.Retail.Contracts.IOutletReportingContract_v2" />
<endpoint address="mex" binding="mexHttpsBinding" name="IMetadataExchange" contract="IMetadataExchange" />
</service>
And here is the error message that appears in the event viewer:
WebHost failed to process a request.
Sender Information: System.ServiceModel.Activation.HostedHttpRequestAsyncResult/28075619
Exception: System.Web.HttpException (0x80004005): There was no channel actively listening at 'https://phil-pc.company.local/Services/Retail/OutletService.svc/_vti_bin/ListData.svc/$metadata'. This is often caused by an incorrect address URI. Ensure that the address to which the message is sent matches an address on which a service is listening. ---> System.ServiceModel.EndpointNotFoundException: There was no channel actively listening at 'https://phil-pc.company.local/Services/Retail/OutletService.svc/_vti_bin/ListData.svc/$metadata'. This is often caused by an incorrect address URI. Ensure that the address to which the message is sent matches an address on which a service is listening.
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result)
Process Name: w3wp
Process ID: 8148
A bit stumped now and would appreciate any help :)
You need to separate your services declaration in web.config.
Assuming your implementation classes are named OutletService_v1 & OutletService_v2 you should end up with something like that:
<services>
<service name="Company.Services.Ticketing.Retail.OutletService_v1" behaviorConfiguration="Public">
<endpoint binding="wsHttpBinding" bindingConfiguration="Standard" contract="Company.Services.Ticketing.Retail.Contracts.IOutletReportingContract_v1" />
<endpoint address="mex" binding="mexHttpsBinding" name="IMetadataExchange" contract="IMetadataExchange" />
</service>
<service name="Company.Services.Ticketing.Retail.OutletService_v2" behaviorConfiguration="Public">
<endpoint binding="wsHttpBinding" bindingConfiguration="Standard" contract="Company.Services.Ticketing.Retail.Contracts.IOutletReportingContract_v2" />
<endpoint address="mex" binding="mexHttpsBinding" name="IMetadataExchange" contract="IMetadataExchange" />
</service>
</services>

Hosting two WCF services using a single console app

I am trying to host two services using a single console app. However, when I am trying to do so, only one service gets hosted, while the other does not.
Program.cs:
namespace WWWCFHost
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(WWWCF.Login)))
{
host.Open();
Console.WriteLine("Service1 Started");
}
using (ServiceHost host1 = new ServiceHost(typeof(WWWCF.UserRegistration)))
{
host1.Open();
Console.WriteLine("Service2 Started");
Console.ReadLine();
}
}
}
}
App.config
<configuration>
<system.serviceModel>
<services>
<service name="WWWCF.Login" behaviorConfiguration="WWWCF.mexBehaviour1">
<endpoint address="Login" binding="basicHttpBinding" contract="WWWCF.ILogin">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080"/>
</baseAddresses>
</host>
</service>
<service name="WWWCF.UserRegistration" behaviorConfiguration="WWWCF.mexBehaviour2">
<endpoint address="UserRegistration" binding="basicHttpBinding" contract="WWWCF.IUserRegistration">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8090"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WWWCF.mexBehaviour1">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
<behavior name="WWWCF.mexBehaviour2">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
As in the code above, I am trying to host one service on port 8080 and the other on port 8090. When I run the application, the first service starts and then closed automatically and the second service remains started. How can I host both the services simultaneously ?
I have gone through the link : Two WCF services, hosted in one console application
I have gone through other threads as well.But they do not solve my issue.
Will be happy to provide any further details if required.
Your first service jumps out of the using block and so is disposing too early. Try this...
using (ServiceHost host = new ServiceHost(typeof(WWWCF.Login)))
using (ServiceHost host1 = new ServiceHost(typeof(WWWCF.UserRegistration)))
{
host.Open();
Console.WriteLine("Service1 Started");
host1.Open();
Console.WriteLine("Service2 Started");
Console.ReadLine();
}
Take a look at this: http://msdn.microsoft.com/en-us//library/yh598w02.aspx
You're instantly closing the first, since it's in the using. You need to set it up so the first using scope doesn't end until after the ReadLine() call.
Try:
using (ServiceHost host = new ServiceHost(typeof(WWWCF.Login)))
{
host.Open();
Console.WriteLine("Service1 Started");
using (ServiceHost host1 = new ServiceHost(typeof(WWWCF.UserRegistration)))
{
host1.Open();
Console.WriteLine("Service2 Started");
Console.ReadLine();
}
}

Windows service stopped without any errors

I created a windows service to host some WCF services,
but when I start it, it stop with a message:
I checked windows log viewer and there isn't any errors
and I tested everything on a console application before and it's working.
My code is:
ServiceHost host1;
ServiceHost host2;
ServiceHost host3;
public ServicesHost()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
if (host1 != null)
host1.Close();
if (host2 != null)
host2.Close();
if (host3 != null)
host3.Close();
host1 = new ServiceHost(typeof(Service1));
host1.Open();
host2 = new ServiceHost(typeof(Service2));
host2.Open();
host3 = new ServiceHost(typeof(Service3));
host3.Open();
}
protected override void OnStop()
{
host1.Close();
host1 = null;
host2.Close();
host2 = null;
host3.Close();
host3 = null;
}
app.config:
<?xml version="1.0" encoding="utf-8" ?>
<service behaviorConfiguration="MyServiceBehavior"
name="Service2">
<endpoint address=""
binding="basicHttpBinding"
contract="IService2">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Service2" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="MyServiceBehavior"
name="Service3">
<endpoint address=""
binding="basicHttpBinding"
contract="IService3">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Service3" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
Edit:
I have installer:
[RunInstaller(true)]
public partial class ServiceInstaller : System.Configuration.Install.Installer
{
private System.ServiceProcess.ServiceProcessInstaller process;
private System.ServiceProcess.ServiceInstaller service;
public ServiceInstaller()
{
process = new System.ServiceProcess.ServiceProcessInstaller();
process.Account = System.ServiceProcess.ServiceAccount.NetworkService;
service = new System.ServiceProcess.ServiceInstaller();
service.ServiceName = "WCFHostService";
service.DisplayName = "WCFHostService";
service.Description = "WCF Service Hosted";
service.StartType = System.ServiceProcess.ServiceStartMode.Automatic;
Installers.Add(process);
Installers.Add(service);
}
}
When a console/desktop application runs but not as service, it's mostly a userright problem. This applies on like, using COM/DCOM or the use of files, because the current path for a service is the windows\system32.
Try to wrap the OnStart with try/catch and write the exception to the EventLog -> http://support.microsoft.com/kb/307024
Did you create any installers for the service?
How to: Add Installers to Your Service Application http://msdn.microsoft.com/en-us/library/ddhy0byf.aspx
Well, you are not logging at all. A window service should have a good logging system to survive in the production/mainteinance phase. Add a loggin system, put a try catch in the start, catch and log the exception in a file, this will hel you for the problem you are facing now, but help every day in your project lifetime.

WCF Array Always Acting as DataSet

I am building a simple self-hosting WCF service that will host a mapping service for multiple products.
Here is my Interface:
namespace Eps.Messaging.Mapper.MapperServiceLibrary
{
[ServiceContract]
public interface IMapperService
{
[OperationContract]
public MapperOutput Map(String MapperFilename, String Input, GlobalArgument[] InputArguments);
[OperationContract]
public List<string> GetAvailableMaps();
}
[DataContract]
public class SymphoniaGlobalArgument
{
[DataMember]
public String Name { get; set; }
[DataMember]
public String Value { get; set; }
}
}
I simply am inheriting IMapperService and implementing them as needed in the service side.
Here is the config for the binding:
<services>
<service name="Eps.Messaging.Mapper.MapperServiceLibrary.MapperService">
<endpoint address="" binding="wsHttpBinding" contract="Eps.Messaging.Mapper.MapperServiceLibrary.MapperService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8755/Design_Time_Addresses/Eps.Messaging.Mapper.MapperServiceLibrary/MapperService/" />
</baseAddresses>
</host>
</service>
</services>
On the client side I am creating a service reference in Visual Studio and pointing to this location. Upon creating an instance of the service I do this:
MapperServiceClient Test = new MapperServiceClient();
Test.Map("Test.map", "Blah", BAD_HERE);
Where it says BAD_HERE it is looking for System.Data.DataSet instead of an array.
What am I doing wrong? Or is this correct and I need to do some fancy casting to get it to accept an array?
There's a setting on the Configure Service Reference dialog box that allows you to configure how collection types are dealt with. Modify the value in the Collection type combo box to an appropriate type (eg array).

Expose webHttpBinding endpoint in a WCF service

I created a WCF service and exposed three endpoints which are basicHttpBinding, wsHttpBinding and webHttpBinding. This is a test service for my experiments with WCF. But, whenever I add service reference using the .svc file, I only get two (basic and ws) endpoints. There doesn't seem to be a third (webHttpBidning) endpoint being exposed for some reason.
To reproduce this issue, create a WCF application project, delete the Service1 service, add new item > WCF service named TestService, and change the config file to the following :
<system.serviceModel>
<services>
<service name="WcfTestService.TestService" behaviorConfiguration="TestServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost/WcfTestService/TestService.svc"/>
</baseAddresses>
</host>
<endpoint address="basic"
binding="basicHttpBinding"
contract="WcfTestService.ITestService" />
<endpoint address="ws"
binding="wsHttpBinding"
contract="WcfTestService.ITestService" />
<endpoint address="web"
binding="webHttpBinding"
contract="WcfTestService.ITestService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TestServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
Here is the code for ITestService.cs:
[ServiceContract]
public interface ITestService
{
[OperationContract]
[WebInvoke]
Boolean ValidateUser(User user);
}
[DataContract]
public class User
{
[DataMember(Name = "Name")]
public String UserName { get; set; }
[DataMember]
public String Password { get; set; }
}
and for TestService.svc
public class TestService : ITestService
{
public bool ValidateUser(User user)
{
if (user.UserName == "User" && user.Password == "123")
{
return true;
}
return false;
}
}
I tried different combination of WebInvoke parameters and WebGet parameters, but failed.
Can anyone tell me why the third endpoint is not showing up in the WSDL file?
#decyclone: I have successfully exposed webHttpBindings without any issue. But I found some interesting thing when it get exposed and when it not!
I can see web binding getting exposed in Wcf Test Client.
Here are my configurations
<services>
<service behaviorConfiguration="TestWeb.Service2Behavior" name="TestWeb.Service2">
<endpoint address="" binding="wsHttpBinding" contract="TestWeb.Service2">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="web" binding="webHttpBinding" contract="TestWeb.Service2">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Point to note here is, its working fine using VS2008 with Framework 3.5, VS2010 with Framework 3.5, when I use VS2010 and Framework 4.0 then I can't see WebHttpBinding getting exposed in WCF Test Client, however I can use that binidng to do http post in all cases.
I assume that in Framework 4.0 its not visible by default, even I try enable endpointDiscovery but still no luck!
I have covered this behaviour in my post
Your "web" endpoint will be exposed as a JSON endpoint. It is not compatible with WSDL.
WebHttpBinding is in System.ServiceModel.Web. If you are using vs2010, go to properties of your project, check target framework. By default it points to .Net Framework 4 Client Profile. It should point to .Net Framework 4, then you can find the System.ServiceModel.Web when you will go to Add reference
#decyclone: One way that a javascript client can learn the available methods on a webHttpBinding is to download a WCF javascript proxy with HTML script tags pointing to your endpoint followed by "/js": <script src="http://localhost/WcfTestService/TestService.svc/web/js"></script>

Categories

Resources