WCF web service does not return WSDL - c#

Using wsdl.exe /l:CS /serverInterface, I generated a C# interface from a WDSL document. I've implemented that interface on a WCF class. The resulting service runs locally:
http://localhost:51454/TapasSim.svc
This shows the default site. The problem appears when I append ?wsdl to the URL:
http://localhost:51454/TapasSim.svc?wsdl
Unlike what I expected, this link does not return a WDSL document! Instead, it points back to the exact web page you get without the ?wsdl. As a result, I cannot reference the web service. If I run svcutil.exe it gives this error:
If you were trying to generate a client, this could be because the
metadata documents did not contain any valid contracts or services or
because all contracts/services were discovered to exist in /reference
assemblies. Verify that you passed all the metadata documents to the
tool.
But I would expect that error to have the same cause as the lack of reply to ?wsdl.
What could cause a WCF .svc service not to generate WSDL?

As it turns out, the problem was mixing two technologies. wdsl.exe belongs to the older "Web References" that predate WCF. The newer tool svcutil.exe is meant for generating WCF "Service Reference" interfaces.
So what happened was that WCF looked for [ServiceContract] and [OperationContract] attributes. When it couldn't find any, it silently did nothing.
The silent suppression of this condition is annoying, to say the least. An error like No service with [ServiceContract] attribute found would really have helped.
Note that you can manually add [ServiceContract], but that will leave you with half "Service Reference" half "Web Reference". The result probably will not work.

I had a problem with getting the WSDL via the IE window provided by starting the debugging session. I had to use a separate window, ensuring I put the HTTPS in the URL.
We are hosting our services on 443 (SSL). When you start up the debugger, even though the IE windows shows http: (80), it was listening for traffic on 443. FYI, this is controlled via the project level setting SSL Enabled

Related

Error generating c# proxy with svcutil

I am trying to generate C# proxy class for web service from WSDL file using svcutil. Svcutil returns following errors:
Error: Style Document on header authHeader does not match expected style Rpc.
For every method in service there is additional error message:
"Error: Extensions for operation 'methodName' in binding CBS cannot specify different values."
I have tried to access service using soapUI and same WSDL file and it works without a problem.
I have no control over service and no direct communication with team that develops it.
This is link to WSDL.
After a lot of discussions with developers that created the service, we concluded that there are some compatibility problems between .NET and Java.
Service developers made several changes on their side and at one moment, it started working on my side.

Get metadata out of a webHttpBinding endpoint

With a reference to my previous question, I would like to know how would I extract information of a WCF service from a client application to know what methods/types are exposed if the service exposes only one endpoint that uses webHttpBinding?
Just to summarize, in my previous question, I came to know that an endpoint using webHttpBinding does not get exposed in the generated WSDL because it would be a JSON endpoint and is just not compatible.
WebHttpBinding is a REST-based binding - REST does not expose metadata like WSDL/XSD contrary to SOAP.
There's no way to extract the metadata from a REST endpoint at this time. There are some efforts under way to establish a similar construct for REST called WADL (Web Application Description Language) - but that's nowhere near standardized yet.
For now, with REST endpoints, you have to either figure it out yourself, or you need to have some documentation provided by the service provider on e.g. a static HTML page or something.
.NET 4 does provide some level of an automatically generated help page - see this blog post or the MSDN docs for more info. But it's still nowhere near as formalized and machine-interpretable as WSDL/XSD.
I wonder why the REST samples tell you to expose a MEX endpoint at all. It is not needed and here is how to cleanly remove it:
Remove MEX endpoint from the service section of the config file.
Remove service metadata enabled line in the service behaviour section of the config file.
Edit the Visual Studio project (assuming it's a WCF service library) and remove the line:
<StartArguments>/client:"WcfTestClient.exe"</StartArguments>
If you have other non-rest services you will want to leave the last 2 parts present. You must remove the WCF Client when disabling MEX otherwise it will complain during debugging if it cannot enumerate any services in the project (regardless whether they have any useful metadata or not).

WCF webservice running on a two server cluster, with loadbalancer, resolving web service address

Apologies for the long winded title but looking for a solution to what might be a common problem.
We have a loadbalancer with address, say: www.myloadbalancer.com
Below are two web servers
First server: webserver1.farm.com
Second server: webserver2.farm.com
We deployed a webservice on to the two servers but noticed something funny when trying to consume the web services somewhere else.
We deploy to:
webserver1.farm.com/service1.svc and
webserver2.farm.com/service1.svc
Because the web servers are not directly accessible online you have to go through the load balancer.
So the address to consume is www.myloadbalancer.com/service1.svc.
However what we are finding is that if the loadbalancer directs you to server 1, and you check the WSDL, you see the service name and details as webserver1.farm.com/service1.svc not www.myloadbalancer.com/service1.svc.
If you attempt to consume www.myloadbalancer.com/service1.svc, say in Visual Studio 2008, you get a warning that webserver1.farm.com/service1.svc does not exist.
The main question is, is it possible to give an alias name to a webservice.
in other words is it possible to get the service to describe itself as www.myloadbalancer.com/service1.svc regardless of whether we end up on web server 1 or 2?
A WSDL file is a WSDL file. Edit it to point to the correct URL. (You don't have to use the auto-generated http://webserver1.farm.com/service1.svc?WSDL if you don't want to.)

WCF Service Browsing

I have a WCF service installed on my system. I can browse and see the .svc file just fine. Should I be able to use a browser to view the endpoint addresses such as https://svc.example.com/BaseService/Login
No, you shouldn't. The fact that some frameworks allow you to do so is a nicety that is provided by those frameworks to make debugging your service easier.
There is nothing in the WS specs (AFAIK) which indicates that contract endpoints should be browsable through a web browser from the root.
Given that the WS specifications are not transport-specific (i.e. HTTP), what would you do over another transport, say TCP/IP, where you have no browser support?
This is why it isn't mandatory. It's only because you typically see WS implementations over the HTTP protocol that this is provided by some frameworks for you.
If your WCF service returns back an HTML page, then yes it should be browsable. But as casperOne says, it's just a nice-to-have. When going to production mode though, you should turn off the WSDL browsable feature to increase security for your service.

Call web service over https

What do I need to call a web service over https in C#?
Do I need to get the certificate form the site? How do I use this to call the web service?
There's nothing special or different for calling a web service over https than over http. You generate a client proxy from the WSDL using either svcutil.exe (or Add Service Reference in VS) or wsdl.exe and invoke the method. The lower level classes HttpWebRequest and HttpWebResponse will eventually take care of the actual call and certificates but it should be transparent for your code. Of course the server hosting the web service needs to provide a valid certificate.
I take that you are using Visual Studio to create your projects, if you are it is pretty easy to do. I take that you have the url for the web service that you would like to connect to and it starts with HTTPS.
In your project in the solution explorer (assuming you using Visual Studio), you should see a node saying "References" and another one saying "Web References". Right click on the "Web Reference" and then basically follow the wizard. It is pretty straight forward. You can spec your own Namespace. I usually use the format SomethingAPI. Then use the API as you would like any other object in your project. You will get the intellisense and all.
There might occur known problems with some certificates though. See http://support.microsoft.com/kb/823177/en-us
Do you have a client certificate that has been supplied by the provider of the web service?
If so, there are various different ways of doing this depending upon which version of .NET you are using. What version are you using, and are you limited in how you can generate your client proxy classes?

Categories

Resources