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
Related
I have a wcf application. It has "Service1.svc" file. In the web.config file I specified
http://localhost:2005/EmployeeService.svc
as an endpoint. When clicking browse from Visual Studio there is no problem. But, when I hosted it on IIS server I get a blank page. The interesting thing is, If I remove the address from the web. config this time I can see the service at this address.
http://localhost:2005/EmployeeService.svc
web.config file is as below:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="EmployeeServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="EmployeeServiceBehaviour" name="EmployeeConfiguration">
<endpoint address="http://localhost:2005/EmployeeService.svc" binding="basicHttpBinding"
bindingConfiguration="" contract="IEmployeeConfiguration" />
</service>
</services>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
</system.web>
<system.webServer>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Could you please explain, why I get a blank page on IIS when I provide the adress.
This may happen in HTTP Activation is not installed in Programs and Features in your Windows installation. Check HTTP Activation for both .Net 3.5 and 4.6 to enable opening WCF service via HTTP request to .svc file hosted in IIS.
I think you can remove all text on the address before Service.svc. This might be an issue with different urls.
When you specify the address part, you tell WCF the service is only available on that address. When going through the endpoints, WCF will not find one that matches the given URL and bail out.
When you have multiple endpoints you need the address field. Otherwise you don't.
Read http://msdn.microsoft.com/en-us/library/ms733749(v=vs.110).aspx
And in particular this part:
When hosting with IIS, you do not manage the ServiceHost instance yourself. The base address is always the address specified in the .svc file for the service when hosting in IIS. So you must use relative endpoint addresses for IIS-hosted service endpoints. Supplying a fully-qualified endpoint address can lead to errors in the deployment of the service.
Check if Service attribute in SVC markup equals your implementation class.
Check endpoint contract name. It has to be exactly full name of your interface. Don't add assembly name, it won't work.
Check <serviceMetadata httpGetEnabled="true" />. If false, you get blank page too.
And 4th change which helped me (but I have no idea why): Remove behavior name <behavior name=""> and remove behaviorConfiguration attribute from service element. It becomes default so the behavior will be used anyway.
Be sure you made an Application Pool with active user like this: https://stackoverflow.com/a/19654633/2148387
Be sure you created Web Application where your WCF is hosted
Check if AppPool and WebApp are running
Enable Directory Browse in your Web.config like here: https://stackoverflow.com/a/19630263/2148387
I'm getting an error when I try to run my WCF Service on IIS instead of ASP.NET Development Server.
Clarification: I don't get an error when I run the WCF Service when using a Windows Service or ASP.NET Development Server. ONLY IIS is the problem.
I'm using a console app to test the service. I've never had problems with the service until i tried using the IIS port.
Here is my app.config file of the console app. The top address and port number is the ASP.NET Dev Server port. The second one is the IIS port.
The following is my App.config file. The top one IIS port. The active one is the ASP.NET Development Server port. When I run the ASP.NET port, I get no errors. When I run the IIS port, I get an error. (Also I have about 4 ASP.NET ports appearing on my Taskbar. I don't know why.)
My App.config file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IWebService" />
</wsHttpBinding>
</bindings>
<client>
<!-- <endpoint address="http://localhost:9876/Service.svc" binding="wsHttpBinding"-->
<endpoint address="http://localhost:5182/Service.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IWebService"
contract="MyWCF_ServiceReference.IWebService"
name="WSHttpBinding_IWebService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Here are some images.
This is the error message that I'm getting.
Is there a reason why the address below is different from the previous ones?
http:// localhost:8732 /Design_Time_Addresses/WCFServiceLibrary/WebService/mex
This is where it is crashing for some unknown reason. Its worth noting that part of the service works. Its only when it get to ValidPerson that it crashes.
(This also doesn't happen when using the ASP.NET Development Server port 5182. Only when using IIS port 9876)
This shows that at the WCF Service itself, the ValidPerson is actually working.
Here is the conf file its running on.
I hope you guys can help me. It must be something simple.
Ok, i wasn't asking the right question although i was learning as I went.
I need to make sure the address in the config file matched either the ASP.NET development server's address (which is mostly likely the default) or change it to the IIS address which would require me to check where the WSDL was being hosted adn use that address instead of the default one. Or use the addrress assigned to my Windows Service which i could find by opening up the project file and seeing which number and address was assigned to it.
The real problem was that my Application Pool account in SQL Server needed to be set to a role of db_owner. Then all my problems went away (once i got it on the right ports with the right addresses.)
I've been battling with this for days, literally going through a hundred articles giving partial guidelines on how to set up a WCF TCP based service in a web application. If someone can help me, I will make this question into a complete guideline.
Current status
The net.tcp connection works on my development machine. It also works locally after being deployed to a Windows Server 2008 R2. However, it doesn't work remotely, even though it's possible to telnet to port 808 on the server remotely. Scroll to the bottom of the question for details. Please help if you can.
I will create a new question for this detail and update this question with the answer if I get a result out of it.
Code
I created ServerHubService.svc with the following content:
namespace Manage.SignalR
{
[ServiceContract]
public class ServerHubService
{
[OperationContract]
public void UpdateServerStatus(string serverStatus)
{
// Do something
}
}
}
Configuration of the application hosting the service
Following an online tutorial, I added the following to my Web.config (I tried MANY different variations). This is the Web.config of the web application hosting the service that I later want to connect to with TCP.
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="ServerHubBehavior"
name="Manage.SignalR.ServerHubService">
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="portSharingBinding"
name="MyServiceEndpoint"
contract="Manage.SignalR.ServerHubService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex"
binding="mexTcpBinding"
bindingConfiguration=""
name="MyServiceMexTcpBidingEndpoint"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://test.mydomain.com:808/SignalR/ServerHubService.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServerHubBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="portSharingBinding" portSharingEnabled="true"/>
</netTcpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
minFreeMemoryPercentageToActivateService="0" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
</configuration>
httpGetEnabled="true" is important because otherwise you cannot create a service reference to the service.
Configuration of the server where the web application is running
I am setting this up on my development machine which has IIS 7.5
I read that IIS Express (built into Visual Studio) doesn't support net.tcp, so I set up a new website in IIS 7.5 using .NET 4.5 and that has a net.tcp binding
I also went to Advanced Settings for the website and set Enabled Protocols to http,net.tcp
I ensured that the Windows Feature Non-HTTP Activation is enabled (and restarted). It's a Windows Feature so look for "Turn Windows features on or off" to find this.
Confirming the web application is running
The website works fine for the rest of the web application. I set up test.mydomain.com to point to 127.0.0.1 in my hosts file. I can even visit http://test.mydomain.com/SignalR/ServerHubService.svc and it will show me a nice auto generated page from .NET, explaining how to use this service.
So far so good.
The page generated by .NET tells me to use this address to generate a connection to my service:
net.tcp://computername/SignalR/ServerHubService.svc/mex
Trying to connect to the service as a client
If you do not remember to set httpGetEnabled="true" you will get an error when trying to create a service reference to it. If you use the WCF Test Client (also a tool included in Visual Studio) and didn't set httpGetEnabled, you will get an error like the following:
Error: Cannot obtain Metadata from
net.tcp://computername/SignalR/ServerHubService.svc/mex
If this is a Windows (R) Communication Foundation service to which you
have access, please check that you have enabled metadata publishing at
the specified address. For help enabling metadata publishing, please
refer to the MSDN documentation at
http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata
Exchange Error URI:
net.tcp://computername/SignalR/ServerHubService.svc/mex Metadata
contains a reference that cannot be resolved:
'net.tcp://computername/SignalR/ServerHubService.svc/mex'. Could not
connect to net.tcp://computername/SignalR/ServerHubService.svc/mex.
The connection attempt lasted for a time span of 00:00:04.0032289.
TCP error code 10061: No connection could be made because the target
machine actively refused it [2001:0:4137:9e76:c81:a4c:a547:b2fd]:808.
No connection could be made because the target machine actively
refused it [2001:0:4137:9e76:c81:a4c:a547:b2fd]:808
However, if you've done everything as above, you should be able to add a reference to the service.
Calling methods in the service
When trying to call a simple Hello World method in the service from the WCF Test Client, it returns the following error:
Could not connect to
net.tcp://computername/SignalR/ServerHubService.svc. The connection
attempt lasted for a time span of 00:00:04.0002288. TCP error code
10061: No connection could be made because the target machine actively
refused it.
This is inner stacktrace that is included in with the error:
No connection could be made because the target machine actively
refused it [2001:0:5ef5:79fb:3884:a:a547:b2fd]:808 at
System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot,
SocketAddress socketAddress) at
System.Net.Sockets.Socket.Connect(EndPoint remoteEP) at
System.ServiceModel.Channels.SocketConnectionInitiator.Connect(Uri
uri, TimeSpan timeout)
If you use netstat -an |find /i "listening" to see that nothing is listening on port 808, it's probably because the Net.Tcp Listener Adapter service is not running.
Confirmation
The call goes through now, but some confirmation is needed before it can be declared a success. I need to confirm that this is in fact net.tcp call on port 808 and not actually a call on the http endpoint. I am trying to do this with Wireshark, but it doesn't show up, probably because it's a call happening from and to my local machine.
Deployment
The last challenge to conquer would be to deploy this on a web server, ensuring that what works on the development machine, also works on the web server.
It doesn't work after publish to a Windows Server 2008 R2. It gives the common SocketException: An existing connection was forcibly closed by the remote host.
It works well locally on the server, but it doesn't work remotely.
Here is the checklist used to check the server:
Is the Net.Tcp Listener Adapter service running? Yes
Is the IIS site binding to net.tcp set to 808:*? Yes
Is Enabled Protocols under Advanced Settings for the site in IIS set to http,net.tcp? Yes
Is the server listening on port 808? Yes, checked with netstat -an |find /i "listening"
Is a port 808 open in the firewall? Yes.
Firewall is turned off on the server.
I can telnet to the server on port 808 from outside with telnet mydomain.com 808
In the configuration of the service on the server, the following was confirmed:
baseAddress is adjusted to net.tcp://mydomain.com:808/SignalR/ServerHubService.svc
This was localhost before, but changed to mydomain.com after it didn't work on the server: <identity><dns value="mydomain.com" /></identity>
It has been tested with a client locally on the server and on another server. Both can connect to port 808 with telnet and both give the same error message.
What configuration could be missing on the server? I am so close to the goal. Please assist me in troubleshooting this and complete the question.
Here is the client configuration on the server calling the service:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="MyServiceEndpoint" />
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://mydomain.com:808/SignalR/ServerHubService.svc"
binding="netTcpBinding" bindingConfiguration="MyServiceEndpoint"
contract="ServerHubService.ServerHubService" name="MyServiceEndpoint">
<identity>
<dns value="mydomain.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I also tried without 808 configured in the endpoint, as this is rumored to be the default port for net.tcp connections. However, it still gives the same result.
Instead of trying lots of things randomly, the good question is perhaps: How does one debug something like this? Can I install a program on either server that will tell me exactly WHY this call is being blocked?
With Wireshark configured like this, it's possible to look at the call coming to the server on port 808 and possibly determine why the call doesn't work. However, I have no idea how to analyze this at present time.
Good luck
I gave up and implemented this in the socket layer instead. It worked immediately. I hope this can help someone else, though. I'm setting an answer because many of the issues were solved and it did work locally eventually, so any problem remaining is probably related to me specific environment.
You have to generate the Proxy based on the metadata exposed over HTTP for tcp.(make sure httpGetEnabled is set to true). The address you use at the client should be the hosted address. Please refer the below post.
http://blogs.msdn.com/b/swiss_dpe_team/archive/2008/02/08/iis-7-support-for-non-http-protocols.aspx
In your question you mentioned that you connected to "test.mydomain.com" but the error changed the server to "computername". Then in your comment you mentioned it still failing to connect. If you wish to have the alias returned in the WSDL/MEX Add the useRequestHeadersForMetadataAddress node in your service behavior. Here is the MSDN information on this node: MSDN useRequestHeadersForMetadataAddress node
This is how your config should look. This takes into account answer given by Prasath (httpGetEnabled="true").
<serviceBehaviors>
<behavior name="ServerHubBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="net.tcp" port="808" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
Hosting a TCP Based service in IIS has always been a bear. WCF makes it very easy to run your own service host, listening on your TCP port. My recommendation would be to do that and set it up to run as a Windows Service.
See this article: http://msdn.microsoft.com/en-us/library/ff649818.aspx
I am guessing the issue you are having is that you need to setup the SPN (Service Principal Name) for your WCF service (on the machine) and have it added to the service account under which the service is running.
If you are running it under the default app pool user, then you need to have the SPN configured for the machine.
I know it is troubling, and typically is the surprise waiting fro us devs once our service is ready to deploy to production or pre-production environments.
The SPN is used by Kerberos during the authentication process.
Try using the IP of the machine to resolve your service instead of the hostname. (This is not supposed to require an SPN), replace "test.mydomain.com" by the machine IP address:
<host>
<baseAddresses>
<add baseAddress="net.tcp://192.168.0.253:808/SignalR/ServerHubService.svc" />
</baseAddresses>
</host>
Take a look at these articles:
- Kerberos for the Busy Admin
- WCF on intranet with windows authentication
- For the following post, try to read the one that is not accepted as an answer: What SPN do I need to set for a net.tcp service?
Did you tried to host service (for the testing purpose) in a Windows service on your local machine? This way you will at least know if the problem is on the service side or it's IIS/server configuration.
You have Net.TCP Port sharing service running on the server I guess... haven't found it explicitely stated.
I had a similar problem here today, while calling a net.tcp wcf service from inside an asp.net web api. I won't say that from all the other machines this service has worked for years, but the calls were made wcf self hosting, wcf iis asp.net compatibility hosting -> against the net.tcp service self hosted. When then I published my simple web api calling the same net.tcp service, everything went wrong, and all the connection were aborted without any reason, even the full wcf tracing both sides (service and client) did not helped, just telling the same "connection aborted".
I've already knew that net.tcp comes with the security over transport enabled, using windows authentication to sign and crypt the communication, so well, I just tried to turn off the security and everything start to work properly.
Just give it a try turning off the security in this way both sides (client and service):
<security mode="None"/>
full service binding:
<netTcpBinding>
<binding name="netTcpBinding" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
I hope this can help you too.
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.
Any ideas how to fix this?
UserService.UserServiceClient userServiceClient = new UserServiceClient();
userServiceClient.GetUsersCompleted += new EventHandler<GetUsersCompletedEventArgs>(userServiceClient_GetUsersCompleted);
userServiceClient.GetUsersAsync(searchString);
.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_UserService"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:52185/UserService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_UserService"
contract="UserService.UserService"
name="BasicHttpBinding_UserService" />
</client>
<behaviors>
<serviceBehaviors>
<behavior name="Shell.Silverlight.Web.Service3Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service behaviorConfiguration="Shell.Silverlight.Web.Service3Behavior"
name="Shell.Silverlight.Web.Service3">
<endpoint address=""
binding="basicHttpBinding"
contract="Shell.Silverlight.Web.Service3" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
Could not find default endpoint element that references contract 'UserService.UserService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
Resolved!
I didn't mention that this was a Silverlight application. I had the wcf reference in a DLL which had it's own "ServiceReferences.ClientConfig" file. I moved the contents of the DLL's ServiceReferences.ClientConfig to the main silverlight project and it worked.
I had a run in with the same problem. My application was also a Silverlight application and the service was being called from a class library with a custom UserControl that was being used in it.
The solution is simple. Copy the endpoint definitions from the config file (e.g. ServiceReferences.ClientConfig) of the class library to the config file of the silverlight application. I know you'd expect it to work without having to do this, but apparently someone in Redmond had a vacation that day.
You can also set these values programatically in the class library, this will avoid unnecessary movement of the config files across the library.
The example code for simple BasciHttpBinding is -
BasicHttpBinding basicHttpbinding = new BasicHttpBinding(BasicHttpSecurityMode.None);
basicHttpbinding.Name = "BasicHttpBinding_YourName";
basicHttpbinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
basicHttpbinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
EndpointAddress endpointAddress = new EndpointAddress("http://<Your machine>/Service1/Service1.svc");
Service1Client proxyClient = new Service1Client(basicHttpbinding,endpointAddress);
Just in case anyone hits the same problem whilst using WPF (rather than WCF or Silverlight):
I had this error, when connecting to a Web Service. When my code was in the "main" WPF Application solution, no problem, it worked perfectly. But when I moved the code to the more sensible DAL-layer solution, it would throw the exception.
Could not find default endpoint element that references contract 'MyWebService.MyServiceSoap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
As has been stated by "Sprite" in this thread, you need to manually copy the tag.
For WPF apps, this means copying the tag from the app.config in my DAL solution to the app.config in the main WPF Application solution.
I ran into the same issue, for whatever reason Visual Studio did not update the web config when I first added the service. I found that updating the Service Reference also fixed this issue.
Steps:
Navigate to the Service Reference Folder
Expand it
Right Click and Select update Service Reference
Observe web Config be updated
Change the web.config of WCF service as "endpoint address="" binding="basicHttpBinding"..." (previously binding="wsHttpBinding")After build the app, in "ServiceReferences.ClientConfig" ""configuration> has the value. Then it will work fine.
Rename the output.config produced by svcutil.exe to app.config.
it worked for me.
Do you have an Interface that your "UserService" class implements.
Your endpoints should specify an interface for the contract attribute:
contract="UserService.IUserService"
Not sure if this is an issue.
Endpoint and binding both have the same name
Not sure if it's really a problem, but I see you have the same name for your binding configuration ().
I usually try to call my endpoints something like "UserServiceBasicHttp" or something similar (the "Binding" really doesn't have anything to do here), and I try to call my binding configurations something with "....Configuration", e.g. "UserServiceDefaultBinding", to avoid any potential name clashes.
Marc
Had to add the service in the calling App.config file to have it work. Make sure that you but it after all . This seemed to work for me.
This problem occures when you use your service via other application.If application has config file just add your service config information to this file.
In my situation there wasn't any config file so I use this technique and it worked fine.Just store url address in application,read it and using BasicHttpBinding() method send it to service application as parameter.This is simple demonstration how I did it:
Configuration config = new Configuration(dataRowSet[0]["ServiceUrl"].ToString());
var remoteAddress = new System.ServiceModel.EndpointAddress(config.Url);
SimpleService.PayPointSoapClient client =
new SimpleService.PayPointSoapClient(new System.ServiceModel.BasicHttpBinding(),
remoteAddress);
SimpleService.AccountcredResponse response = client.AccountCred(request);
For those who work with AX 2012 AIF services and try to call there C# or VB project inside AX (x++) and suffer from such errors of "could not find default endpoint"... or "no contract found" ...
go back to your visual studio (c#) project and add these lines before defining your service client, then deploy the project and restart AX client and retry:
Note, the example is for NetTcp adapter, you could easily use any other adapter instead according to your need.
Uri Address = new Uri("net.tcp://your-server:Port>/DynamicsAx/Services/your-port-name");
NetTcpBinding Binding = new NetTcpBinding();
EndpointAddress EndPointAddr = new EndpointAddress(Address);
SalesOrderServiceClient Client = new SalesOrderServiceClient(Binding, EndPointAddr);
In case if you are using WPF application using PRISM framework then configuration should exist in your start up project (i.e. in the project where your bootstrapper resides.)
In short just remove it from the class library and put into a start up project.