WCF Won't Host in IIS - c#

I've created my service as a WCF Service Application. I've then published the service to a folder called "TestService". I'm trying to add it as a site to IIS Manager. Everything seems to go fine until I go to browse to the service I am always greeted with:
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
I'm browsing to this at http://localhost:8734 and the website is hosted in IIS at port 8734. The web.config has the following too:
<service behaviorConfiguration="TestServiceBehavior" name="TestApp.Service.TestService">
<endpoint address="/Authentication" binding="wsHttpBinding" bindingConfiguration="TestServiceBinding"
contract="TestApp.Service.IAuthenticationService" />
// ... other endpoints
<host>
<baseAddresses>
<add baseAddress="http://localhost:8734/Design_Time_Addresses/TestApp.Service/Service1/" />
</baseAddresses>
</host>
Any help would be appreciated.

The service is hosted, you need to browse to the service endpoint eg http://localhost:8734/MyService.svc. The reason you are getting a 403 is because you are trying to browse the directory in which the application is deployed, and this is normally not allowed. You can turn directory browsing on with a web.config setting.

Related

Hosting WCFService Library on IIS 10 with SSL encryption

I am trying to host a WCF Service Library on IIS 10, with a self signed SSL.
To Obtain Minimum Complete Verifiable Example, Open Visual studio 2017
New>Project>C#>Web>WCFLibrary With this you will get a simple code that has one operation contract which takes an integer and returns a string.
Now I am trying to host this on IIS with Self Signed SSL (Mine has more operation contract but this will do).
What I have tried so far.
Now the next part is hosting it on IIS, so I created the SVC file
My SVC file contains ->
<%# ServiceHost Language = "C#" Debug = "true" Service = "WcfServiceLibrary2.Service1" %>
Then all the tutorials that I can find edit Web.Config, which is unavailable in Visual Studio 2017, so I tried two things
1. Created a Web.Config file and added the configurations
2. Published the website and then obtained Web.Config which did not require any changes
Then I went on to IIS (as administrator) and added a new website
Then while trying to browse, to see the message that IIS service is hosted I got this error "Cannot read configuration file" To Solve this I followed success.trendmicro.com/…
Now that error is gone but now I am getting
To solve this I Followed
IIS - 401.3 - Unauthorized But this lead to the browser letting me browse the directories rather than giving the message that a Service has been created.
Any Idea what I am missing here?
Definitely I am missing something major here as I have failed to host it on HTTP itself, All the tutorials I find online have a file Web.Config and not App.config, I am looking for an example (preferably with Images) that demonstrate it just with this small example.
I know this doesn't follow all SO guidelines on asking questions, but I have failed to articulate it into a question that does.
Edit
As per LexLi's advice that it may already be hosted, I went and tried to consume it using svcutil which gave me the error
WS-Metadata Exchange Error
URI: http://localhost/Service1.svc
Metadata contains a reference that cannot be resolved: 'http://localhost/Service1.svc'.
The remote server returned an unexpected response: (405) Method Not Allowed.
The remote server returned an error: (405) Method Not Allowed.
HTTP GET Error
URI: http://localhost/Service1.svc
There was an error downloading 'http://localhost/Service1.svc'.
The request failed with HTTP status 404: Not Found.
The Url is correct because I obtained it by using the browse functionality from IIS.
First, please don’t set the IIS physic path to desktop, which will cause the permission problem. we could set the IIS site physical path to the folder under C partition.
Second, please read the following link, which mainly indicates that WCF service library project could not published directly to IIS since its Appconfig could not be recognized by IIS unless additional Webconfig is added manually in the root directory of the web site.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/deploying-a-wcf-library-project
Generally speaking, we use the WCF service project template which contains an auto-generated Webconfig file instead of WCF service library project template, since it is generally used as a class library.
By default, the service is hosted with BasicHttpBinding, it depends on the following tag.
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" />
</protocolMapping>
The service could also be configured manually by the following ways. These two ways configuration file is equivalent.
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="mybehavior">
<endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1" bindingConfiguration="mybinding"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="mybinding">
<security mode="None">
</security>
</binding>
</basicHttpBinding>
</bindings>
It is unnecessary to assign the service endpoing address in the webconfig. It should be completed in the IIS site binding module.
WCF System.ServiceModel.EndpointNotFoundException
At last, we could host the service over https by adding an additional service endpoint, refer to the following configuration(simplified configuration).
<protocolMapping>
<add binding="basicHttpBinding" scheme="http"/>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
then add the https protocol in IIS site binding module.
Configuring Web.config to publish WCF Service
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl
Feel free to let me know if there is anything I can help with.
First Credit where credit is due, many of the issues I was pointed in the right direction by multiple SO users to name a few would be: Mikael bolinder, Abraham Qian, Lex Li, the wonderful people in the C# chat room and a co-worker of mine(Doesn't have an account on SO as of writing this answer), In this answer I plan to cover everything you might need to host a WCF Library in IIS Server using HTTPS security.
Tools I used:
Visual Studio 2017 professional
IIS 10 (Comes with windows 10 but has to be activated in windows features ) (See below)
First:
Make sure you have all the components you will need from visual studio installed.
Windows -> .Net Desktop Development
Windows -> Universal Windows platfor development
Web & Cloud -> ASP.NET and web development
In this list and among other list that will come, some extra components may be included, the reason for that is I installed them and couldn't verify one way or the another if they are absolutely necessary.
Now, let's add the windows features necessary. Control Panel -> Programs -> Turn Windows features on or off
Make sure to go into WCF Services and check HTTP Activation, don't be fooled by the square block (One of my mistakes)
Now let's get to creating the Service. Open Visual Studio File -> New -> Project -> Visual C# -> Web -> WCF -> WCF Service Library This generates the MCVE that you are trying to host
Now you have to link it with a website in order to generate the Web.Config file along with the SVC file, to do that, On Solutions Explorer, right click on your solution, Add-> New Website.
Now in the web.config file add
<system.serviceModel>
<services>
<service name="WcfServiceLibrary4.Service1"> <!-- Change the library name as per your need -->
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="secureHttpBinding"
contract="WcfServiceLibrary4.IService1"/> <!-- Change the library name as per your need -->
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="secureHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Next add reference to service on the website
Discover services and add the service you have created. Now Build your solution and publish it. **Careful Don't publish the solution in a user Directory like Desktop or documents or else ACL permissions will give you a headache, rather publish it directly in a directory in Drive.
Now Hosting time
First lets open IIS (Always as admin) and create a new certificate.
On the server go to the IIS part and Select Server Certificates, then click create new certificate on the right end.
Now create a new website from the left menu
Make sure to switch to https and select your certificate here, Now to verify that your service is created you will need to browse your websites svc file created, sadly at this point you will get an error saying Server Error in '/' Application.
Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https]. I was unable to find the cause of the error, but I was able to find a bypass of it,
Steps to bypass this error -> Select you website from the menu on the left, on the menu at the right click bindings and also add an HTTP binding, with a different port.
After this you will be able to browse the HTTPS version of your svc file.
Now if you browse the HTTPS link you get the message that the service is created
Now you can go Ahead and create an application that consumes this service.
What lies ahead
I will try to find a way to do this without adding an additional binding
The Second goal would be to achieve this without adding the extra website.
If and when I achieve these I will update, however these are not my priority right now and may not be added for quite a while, if anything didn't make sense, or you have any ideas of improvement comment below.
In short here are the steps :
Create Self-Signed Certificate
Add SSL Binding
Configure Virtual Directory for SSL
Configure WCF Service for HTTP Transport Security
This link is more in depth : https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl

Relative path to WCF service from MVC web config path

So the story is that I need multiple test sites on a single IIS.
My application consists of a MVC project with a web.config file pointing towards the WCF Service located on the same server.
I have this folder structure on the IIS:
Developer1
-MVC
-WCF
Developer2
-MVC
-WCF
I have configured IIS so the devs can access
http://MyServer/Developer1/MVC
or
http://MyServer/Developer2/MVC
I have tried setting this path in the web.config file to contact the correct WCF "~/WCF/SomeService.svc" and "../WCF/SomeService.svc" but I can't get it to work and I can't find the correct syntax.
Why do you want to use a relative path? You could register both endpoints and use the one you need:
<endpoint name="dev1" address="http://MyServer/Developer1/MVC/WCF/SomeService.svc" binding="basicHttpBinding" contract="SomeServiceContract" />
<endpoint name="dev2" address="http://MyServer/Developer1/MVC/WCF/SomeService.svc" binding="basicHttpBinding" contract="SomeServiceContract" />
var svcProxy = new SomeServiceProxy("dev1");

Attempting to download metadata from 'net.pipe://localhost/abc.svc' using WS-Metadata Exchange. This URL does not support DISCO

Got this error while generating proxy by svcutil:
"Attempting to download metadata from 'net.pipe://localhost/abc.svc' using WS-Metadata Exchange. This URL does not support DISCO."
The service is compiled without error & working fine with http earlier.
The wsdl generated is working fine for net.pipe too without problem even after the error while generating proxy with svcutil.
To make sure its generating new files are generated, I deleted all old files & then generate files using svcutil, then use them. It gives same error and also generates files which when used gives no problem while consuming services.
I am just puzzled why this error is there when every thing is working fine.
Pranav,
your mex endpoint is right. When you are using netNamedPipeBinding or netTcpBinding you need to make some settings in services and IIS.
Refer Hosting WCF service with netTcpBinding or netNamedPipeBinding in IIS
That is not ERROR message. I would say just INFO, not even WARNING...
I guess you have something like the following config and try to run svcutil on net.pipe.
<service name="Service" ...>
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/" />
</baseAddresses>
</host>
<endpoint address="Service"
binding="netNamedPipeBinding"
contract="IService" />
<endpoint address="Service/mex"
binding="mexNamedPipeBinding"
contract="IMetadataExchange" />
</service>
...
<serviceMetadata httpGetEnabled="False" />
svcutil will give message like "This URL does not support DISCO" and still successfully generate files
Now you can change serviceMetadata to
<serviceMetadata httpGetEnabled="True" httpGetUrl="http://localhost:8182/Service/mex" />
and run for example
svcutil.exe /t:code /l:cpp /ser:Auto http://localhost:8182/Service/mex
It will generate the same client proxy code as running on net.pipe but now with following output...
Attempting to download metadata from 'http://localhost:8182/Service/mex' using WS-Metadata Exchange or DISCO.

Windows Service Hosted TCP WCF Service

I am trying to host a WCF service on a windows 2008 R2 server as a windows service. I followed the directions provided by msdn (found here). Everything works fine as long as everything is part of the same solution in visual studio. However, I tried creating a client in a different solution (on the same machine) and it can't find the service. I get an 'Add Service Reference Error' shown below.
My goal is to be able to access the wcf service remotely, but I can't seem to even access it locally unless the client was created within the same client. Is there any guides, tutorials, or helpful hints that anyone can give me to get this to work?
Update:
It seems that even though the windows service is running, the WCF service doesn't seem to be listening to any ports. Which would suggest that it isn't running. This also explains why everyone's first thought I didn't have the service running. I had assumed that since the windows service was running and that the same solution client worked, that the WCF service was working as well. Turns out that Visual Studio was starting up a WCF service whenever I ran the same solution client.
So, why isn't the windows service starting the WCF service? Any ideas?
It turns out that there was a problem with the tutorial provided by MSDN (provided in the question above). They named both the windows service and the WCF service Service1 which is the default name for both of them.
The windows service was suppose to start the WCF service, however, it was actually trying to start itself again because both services had the same name.
myServiceHost = new ServiceHost(typeof(Service1));
To fix this problem, you can rename one of the services or fully qualify the WCF service when referenced in the windows service.
myServiceHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
The funny thing is that the code provided still looks like it works because Visual Studio is smart enough to notice that the WCF service isn't running and it starts an instance up behind the scenes.
It was a simple bug to fix, but because Visual Studio was hiding the problem from me, I don't think I would have found it without the help from Espen Burud.
There are two ways for Add Service Reference to learn about a service:
Discover button: searches the projects in the current solution.
Go button: connects to the service in the Address box and retrieves the metadata.
You need to actually have the service running before you click Go.
EDIT
I just noticed from your screenshot that you're trying to connect to a net.tcp URL. I think it's more common to use http for MEX. Your app.config would look something like:
<services>
<service behaviorConfiguration="WcfServiceLibrary1.Service1Behavior"
name="WcfServiceLibrary1.Service1">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="WcfServiceLibrary1.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8523/Service1" />
<add baseAddress="http://localhost:8524/Service1" />
</baseAddresses>
</host>
</service>
</services>
Note the different port number for the http base address. You would then use "http://localhost:8524/Service1" in the Add Service Reference tool. You should also be able to connect to it with your web browser.
To allow metadata exchange via http GET (e.g. from a browser), you also need to enable it via a behavior:
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
I'm not sure if the Add Service Reference tool cares about that.
Even if you don't want to allow http get access (httpGetEnabled="False"), you still need to include this behavior to enable MEX (unless you're adding it programatically).
I have tested the MSDN article in the and it works without modifications. If the firewall is enabled on the server, I think you will need to add some rules for your service.
To verify that the service are listening on the correct tcp port, you can use command: netstat -a. If the service are listening on the correct port, this command will return:
Proto Local Address Foreign Address State
TCP 0.0.0.0:8523 machinename:0 LISTENING
I managed to figure out the issue. My service didn't know about the endpoints because I hadn't copied the service configuration from the app.config in the WCF project into the app.config of the actual windows service. Once I did that it functioned correctly.
This was not made clear in the original MSDN article which I had also followed although it is mentioned in a comment in the WCF app.config.

WCF hosting in Windows Services (Network Service)

WCF Service
WCF service hosting in Windows Services
WinService log on as Network Service
Host app config :
<service name="StudyingControllerService.ControllerService">
<host>
<baseAddresses>
<add baseAddress="http://IP:PORT/ControllerService.svc"/>
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IControllerService"
contract="StudyingControllerService.IControllerService" />
</service>
Everything work fine in local network. (localhost)
But I want to access my service from another computers via network.
I used another computer(from another localation), did ping IP (winservice's). ping was OK.
I installed my client and tried to connect to my remote service, but connect failed.
telnet also can't establish connection.
What is wrong?
Firewalls are disconnected. (on both sides)
On the client side telnet cant open connection to IP PORT
There is no problem with windows service or WCF. Problem was with my internet provider.
It blocked port which used my service. So, I ask to administrator to open port. and now everything is OK.
Thanks all for answers.
I had a similar issue. It was just abut opening the PORT on windows firewall.
Just to test if that would work, i turned off the firewall service.
Hope that helps!
I would try changing your base address in your config file, as follows:
<service name="StudyingControllerService.ControllerService">
<host>
<baseAddresses>
<add baseAddress="http://IP:PORT"/>
</baseAddresses>
</host>
<endpoint address="ControllerService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IControllerService"
contract="StudyingControllerService.IControllerService" />
</service>
My reason for recommending this is that the base address is used to allow endpoints to be added relative to the base address - putting the endpoint in the base address may be causing the issue.
Something to try at least - a couple minutes of editing and you'll have an answer one way or the other.

Categories

Resources