Problems Deploying a hosted WCF Service in a Windows Service - c#

I have a WCF Service which I am hosting in a windows service. The Windows host service has an App.config to consume a service endpoint and the service has an App.config which exposes the metadata endpoints. When the service is deployed via the VS development system it all works great. With a Web Browser loaded, the http://localhost:9001/ url resolves to the metadata webpage exposing the wsdl link for the service. It even works with the WCF Test Client as well and I can send the service messages and it responds.
However, with the projectInstaller loaded on the hosted service in VS and deployed outside of the VS development system, I can no longer access the http://localhost:9001/ metadata endpoint when the hosted service is deployed in Windows. The service is started and running, but the endpoint doesn’t respond. The Service is deployed from the debug folder using the “sc create binpath= “Service.exe” start= auto” command. Maybe this is not the correct way to deploy it, not sure or maybe my app.Config files are not correct or being referenced correctly. Could someone let me know the process for this and maybe verify that my app.Config files are correct for both the windows Host and Service side. This is pretty tricky to configure, so any help is appreciated.
Window host service App.config to consume the endpoints:
<system.serviceModel>
<client>
</client>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding_WindowsService" maxReceivedMessageSize="20000000" />
</basicHttpBinding>
</bindings>
<services>
<!-- Service endpoint to consume -->
<service name="WindowsService.Service">
<endpoint address="http://localhost:9001/Service" binding="basicHttpBinding"
contract="WindowsService.IService" />
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
Service Web.config to expose the endpoints:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding_WindowsService" />
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="defaultbehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="defaultbehavior" name="WindowsService.Service">
<!-- Base address for exposing Metadata and Service -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:9001/" />
</baseAddresses>
</host>
<!-- Metadata service endpoint to expose -->
<endpoint address="" binding="mexHttpBinding" contract="IMetadataExchange" />
<!-- Service contract endpoint to expose -->
<endpoint address="Service" binding="basicHttpBinding" contract="WindowsService.IService" />
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>

Related

Config wcf service for https/SSL on localhost

EDIT: Already fixed it... I only had to change the Project properties and enable SSL.
ORIGINAL QUESTION:
I'm developing a WCF service that will be hosted in an IIS server with SSL certificate.
My code works perfectly fine when I upload it to the server (that have all the certificates), but since I added the security to the web config, it crash when I try to debug it on my local machine.
I'm using the following web config for a SOAP service that don't need the SSL certificate and a REST service that need it:
<configuration>
...
<bindings>
<basicHttpBinding>
<binding name="SOAPEndPoint" />
</basicHttpBinding>
<webHttpBinding>
<binding name="SecureBinding" >
<security mode="Transport"></security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="xxx.WS">
<endpoint address="SOAP" binding="basicHttpBinding" name="SOAPEndPoint" contract="xxx.ISerSoap" />
<endpoint address="api" binding="webHttpBinding" name="RESTEndPoint" contract="xxx.ISerRest" behaviorConfiguration="RestBehavior" bindingConfiguration="SecureBinding"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="RestBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
I want to be able to debug it without the need to change the web config each time I open it during debug and if I have to upload it to the server.
Someone knows a way to bypass the security when I call it in debug mode? Or an easy way to add support of https on my localhost?
Just find that the solution was to activate "SSL Enabled = true" on the project properties windows.

Deploying WCF Service Host App without WCF Service Host?

I have a WCF service hosted by a simple WinForms app. In Visual Studio the service is started via the built in WCF Service Host & everything works fine. I now want to host the service in my host app but currently the service doesn't run.
Service App:
ServiceHost host;
private void btnStart_Click(object sender, EventArgs e)
{
host = new ServiceHost(typeof(RegimesService));
host.Open();
lblStatus.Text = "Started...";
}
If I close WCF Service Host in the sys tray & click my start button, the code runs but the service never starts?
Here's my Service Host App config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="metaBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="diiRegimesService.RegimesService">
<endpoint address="" binding="basicHttpBinding" contract="diiRegimesService.IRegimesService"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8081" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
& Finally my Service project App.config:
<system.serviceModel>
<services>
<service name="diiRegimesService.RegimesService">
<endpoint address="" binding="basicHttpBinding" contract="diiRegimesService.IRegimesService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
When I run netstat -a from cmd line, the port http://localhost:8080 isn't listening so it's like the service object never actually gets initialized. I'm sure it's a simple mistake in my configs somewhere, any ideas? Thanks
Port 8080 is a reserved port for SQL Server, Also your service App.config and Host App.config are having different ports in their base address
Ok, used the WCF configuration wizard from Solution Explorer & tied the ServiceBehaviour to the Service definition in the Host App's App.Config & hey presto, everything is wired up & working! Thanks for your help #Akshay Choudhary.

Enabling http and https on the same service

I am writing a WCF service which contains a singe contract. I would like web clients to call the service endpoint using either http or https.
My web.config is as follows:
(Some parts have been removed for brevity)
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IDataService" />
<binding name="BasicHttpsBinding_IDataService" >
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="DataServiceMetadataBehavior" name="DummyService.DataService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDataService"
contract="DummyService.IDataService"/>
<endpoint address=""
binding="basicHttpBinding" bindingConfiguration="BasicHttpsBinding_IDataService"
contract="DummyService.IDataService" name="BasicHttpsBinding_IDataService"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DataServiceMetadataBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" />
<add scheme="https" binding="basicHttpBinding" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
When I try to test the service using the VisualStudio test client, it gives the following error:
Could not find a base address that matches scheme https for the
endpoint with binding BasicHttpBinding. Registered base address
schemes are [http].
Everything works fine with only a single endpoint.
An endpoint consists of address, binding and contract.
http://YourBaseAddress/YourApp/YourService.svc and httpS://YourBaseAddress/YourApp/YourService.svc are different address with different schema name or protocol as well as different ports: 80 and 443 by default, so you can have both endpoints for the service, with the same basicHttpBinding, provided that the https one has a bindingConfiguration for SSL transportation as you had done. The error message is quite informative, so you need to go to IIS (or IIS Express) to make sure there's a http listener, say https binding defined after checking the "Edit Bindings" function of the Website. After you had done so, you should be able to get WSDL through httpS://YourBaseAddress/YourApp/YourService.svc?wsdl in a Web browser.
In fact, many Web services/applications like those from Microsoft and Google support both http and https through the same host name and path.

invoke WCF service on other machines on the same network not working

I have a WCF Service running on my local machine
Everything themes to be running okay
Question is
if i can Invoke this WCF Service on my local machine browser
why it is not available on other machines
what i have tried :
my service address was localhost : port on the other machine i replaced the localhost with the ip of the machine where my WCF service is running and it didn't work
in my App.config i changed the baseaddress as you can see below from localhost to the machine ip and it didn't work either
i created a web application and call my service using getJson and it worked on my local machine browser and not on any of the other machine it loads the whole page and gives me error on getJson
what i am missing here ??? i don't know
IService1.cs
[OperationContract]
[WebGet(UriTemplate = "GetName/{name}",
ResponseFormat = WebMessageFormat.Json)]
List<Eval> GetName(string name);
App.config
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"></binding>
</webHttpBinding>
</bindings>
<services>
<service name="WcfServiceLibrary1.Service1">
<host>
<baseAddresses>
<add baseAddress = "http://192.168.1.5:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJsonP" contract="WcfServiceLibrary1.IService1" behaviorConfiguration="web">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
WCF Test Client
Browser
It might be that firewall is stopping service call. Open inbound connection on port 8733 on machine where WCF is hosted. In case of Windows, open the Windows Firewall with Advanced Security dialog box, in the left pane, click Inbound Rules, and then, in the right pane, click New Rule and select Port option.

WCF Endpoint. Multiple Clients

I have an IIS hosted WCF webservice. It started with two consumers.
1) A WinForm test harness in the same solution to test the WCF contracts in the IDE.
2) An Asp.Net Web App that is consuming the published version.
All was working out of the box so to speak.
Then along came the 3rd consumer, an Android app. To get this consuming correctly had to decorate the WCF contracts with JSON WebGets and Webinvokes and alter the WCF Web.config to suit.
Now the original two consumers no longer work. So I need to alter Web.config and / or App.configs to get a configuration where all three work.
Focusing on the IDE first. I have the following service model section for the WCF service Web.Config.
<system.serviceModel>
<client>
<endpoint binding="webHttpBinding" bindingConfiguration="JsonBinding"
contract="CouponParkingWCF.ICouponService" name="Json"
kind="" endpointConfiguration="">
<identity>
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
<endpoint address="http://localhost:8707/CouponParking.svc"
binding="basicHttpBinding" contract="CouponParkingWCF.ICouponService"
name="BasicHttpBinding_ICouponService" />
</client>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" />
</basicHttpBinding>
<webHttpBinding>
<binding name="JsonBinding" />
</webHttpBinding>
</bindings>
<services>
<service name="CouponParkingWCF.CouponService">
<endpoint behaviorConfiguration="JsonBehavior" binding="webHttpBinding"
bindingConfiguration="" name="jsonEndPoint"
contract="CouponParkingWCF.ICouponService" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="JsonBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="false" />
</system.serviceModel>
The WinForm Test harness App.config has:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttp" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8707/CouponParking.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttp"
contract="CouponParking.ICouponService"
name="BasicHttpBinding_ICouponService" />
</client>
</system.serviceModel>
I am not experienced at configuring endpoints and the above has been based on examples and guesswork.
When I run the Test Harness the wcf Client instantiates but a call on a contract fails with :
There was no endpoint listening at http://localhost:8707/CouponParking.svc
that could accept the message. This is often caused by an incorrect address
or SOAP action. See InnerException, if present, for more details."
The inner exception is :
{"The remote server returned an error: (404) Not Found."}
[System.Net.WebException]: {"The remote server returned an error: (404) Not Found."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146233079
InnerException: null
Message: "The remote server returned an error: (404) Not Found."
Source: "System"
StackTrace: " at System.Net.HttpWebRequest.GetResponse()\r\n at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)"
TargetSite: {System.Net.WebResponse GetResponse()}
I would appreciate some guidance on what I have got wrong.
Thanks
At a glance, it appears that you've mixed up client endpoints with service endpoints in your service's config file. There's no reason for client endpoints to appear in the service's config file, unless that service is itself calling another service.
Your WinForm's config file is defining a client with basicHttpBinding, but you do not expose a service endpoint with BasicHttpBinding, which is most likely the reason for the error you're getting.
I would try deleting the client endpoints in your service's config file, and add them to the <services> section, like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" />
</basicHttpBinding>
<webHttpBinding>
<binding name="JsonBinding" />
</webHttpBinding>
</bindings>
<services>
<service name="CouponParkingWCF.CouponService">
<endpoint address="SOAP"
binding="basicHttpBinding"
contract="CouponParkingWCF.ICouponService"
name="BasicHttpBinding_ICouponService" />
<endpoint address="JSON"
binding="webHttpBinding" bindingConfiguration="JsonBinding"
contract="CouponParkingWCF.ICouponService" name="Json"
kind="" endpointConfiguration="">
<identity>
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
</service>
</services>
Remember the ABC's of WCF: A = Address, B = Binding and C = Contract - those three items define a service.
Since you added a client that needed a different binding then your test harness or your ASP.NET application, you need to expose a second endpoint with that binding.
EDITED
As #marc_s pointed out, you'll need two distinct relative addresses. I've updated the config file to reflect that.
I've not had an occasion to use multiple endpoints myself, but I believe you'd use them this way, with the base address being provided by the location of the *.svc file:
http://localhost:8707/CouponParking.svc/SOAP
http://localhost:8707/CouponParking.svc/JSON
With the first being for the BasicHttpBinding and the second being for the WebHttpBinding.
You basically just need two separate endpoints to provide both the basicHttpBinding (a SOAP binding) and the webHttpBinding for your Android client (a REST binding).
The "base" address of your service is defined by your IIS virtual directory and where the *.svc file lives (http://localhost:8707/CouponParking.svc) - so both services will be reachable at this "base" address plus any relative address defined
So you need to configure this something like this:
<services>
<service name="CouponParkingWCF.CouponService">
<!-- define the basicHttp (SOAP) endpoint at the base address -->
<endpoint name="SoapEndpoint"
address=""
binding="basicHttpBinding"
contract="CouponParkingWCF.ICouponService" />
<!-- define the REST endpoint at (base)+"/rest" -->
<endpoint name="RestEndpoint"
address="rest"
behaviorConfiguration="JsonBehavior"
binding="webHttpBinding"
contract="CouponParkingWCF.ICouponService" />
</service>
</services>
With this setup, you should be able to call your service using the basicHttpBinding (SOAP) at
http://yourServer:8707/CouponParking.svc
and you should be able to access the REST-based, JSON-enabled endpoint at
http://yourServer:8707/CouponParking.svc/rest
Both server-side endpoints will be handled by the same service code - it's just the endpoint (and the protocols that endpoints understands) that are different

Categories

Resources