I have a simple service that I deployed to Azure. It is accessible via:
http://xxxxxxxxxxxxxxxxxxxxxxx.cloudapp.net/MyTestService.svc
The URL to the WSDL uses the internal machine name instead of a public DNS:
svcutil.exe http://rd001520d328923a/MyTestService.svc?wsdl
Obviously, the WSDL is not accessible from outside the machine with this.
I am aware of a few things that can be changed if you are running this in IIS, or if you do know the url of the service. For example changing the <serviceMetadata> config to specify the httpGetUrl property, but this will not work as I would have to include the absolute URL. Using a relative URL, it still uses the internal machine name. The real issue is that the WSDL includes URL references with the machine name, therefore rendering it useless.
There are two substandard workarounds:
It has been suggested that I could grab the WSDL, edit it to fix the URLs and then upload it so it is accessible from a different URL.
I found a hotfix from early 2010 was available, but there's got to be a better way.
How can this be solved to have the public facing DNS used instead of the machine name?
Ok. I have been looking at this for almost a week. I finally found the answer, since it is not easily available I hope this gets indexed and save the time for others.
Basically this overall behavior as a known issue with WCF 3.0/3.5, for which they released a hotfix. You can find out more here: FIX: URIs in a WCF WSDL document refer to inaccessible internal instances instead of to the load balancer...
I had come across this a few times during my research but never gave it a 2nd thought, mostly because I had no idea how I would deploy a hotfix into Azure.
Fortunately, a Microsoft moderator at the MSDN forums pointed out that this had been fixed in .net 4.0. What this meant was that the "fix" recommended in the KB article above, still applied, with the exception that no hotfix had to be applied. So what is the solution?
Simple, add the following to the config file:
<serviceBehaviors>
<behavior name="<name>">
<!-- Other options would go here -->
<useRequestHeadersForMetadataAddress>
<defaultPorts> <!-- Use your own port numbers -->
<add scheme="http" port="81" />
<add scheme="https" port="444" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
And that was it.
This would have been a much simpler search if it had been clearer that this issue had now been fixed. Perhaps I didnt look hard enough.
The blog post Using Request Headers for Metadata Address is similar to
Victor's answer, but explains that default ports are optional
and can be omitted:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<useRequestHeadersForMetadataAddress/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
It also shows how to enable the behavior in the code.
sh.Description.Behaviors.Add(new UseRequestHeadersForMetadataAddressBehavior());
Are you generating the WSDL in order to publish it, or are you just trying to add a reference in another project?
If it's the later, my suggestion is to use the WCF ChannelFactory approach rather than "add service reference". I find it gives me more consistent controllable results.
http://msdn.microsoft.com/en-us/library/ms734681.aspx
I must add, I haven't tried this on Azure.
Related
I can get xml content of service via browser
but somehow cant add as service referance in Visual Studio same link with ?wsdl extension.
The error message in visual studio;
The document at the url
http://****?wsdl was not
recognized as a known document type. The error message from each known
type may help you fix the problem:
- Report from 'XML Schema' is 'The root element of a W3C XML Schema should be and its namespace should be
'http://www.w3.org/2001/XMLSchema'.'.
- Report from 'DISCO Document' is 'Discovery document at the URL http://****?wsdl could not be
found.'.
how can I fix it ?
Have you enabled metadata discovery in WCF?
First off you need to add a mex (Metadata exchange) endpoint like this to the service in web.config, if you are declaratively setting up your WCF service (you can do this also programatically):
<service name="myservice">
<endpoint contract="IMetadataExchange" binding ="mexHttpBinding" address="mex" />
<endpoing contract="SomeAssembly.SomeService" address="SomeService" binding="basicHttpBinding" ...
Note that I will not suggest you use BasicHttpBinding as it default is not set up with security, use WsHttpBinding instead for instance.
Now also add this serviceBehavior:
<serviceBehaviors>
<serviceMetadata httpGetEnabled="true" />
You will find this well documented and a good sample for example here:
WCF Service Behaviors – How to Generate Service Metadata to simplify WCF Client Application Development
Then check again if the WSDL link works of your service. You might want to check out the installed features of IIS if is still not working, maybe your IIS config and setup is not correect.
We have created a WCF service application for a customer. Since the service is used to transmit large amounts of data (which can take a long time), some changes (such as increased timeout limits or message size limits) have been made to the Web.config file to accommodate this.
Everything works fine and there are no technical issues... except the client isn't exactly happy that whenever they create a new application which consumes the WCF service they need to manually add all the changes to the client-side App.config file.
They would like to have the changes to be read from the service automatically.
I've never of WCF having such functionality, so I don't think this is possible. But I would very much like to have this confirmed... or denied, if this is actually possible.
IIRC .. in earlier releases of the stocktrader app.
How to implement Configuration Service 5.0 of the StockTrader 5.0 sample application?
mentioned in the above SOF link
There was a way to get configuration from a service.
However, the stocktrader app looks much different now then it did earlier.
So I don't know which version it become something different.
Greg Leake (Leak) was the name of the dude I met at TechEd one year....talking about this, IIRC.
IT IS NOT TRIVIAL TO IMPLEMENT.
The cost of editing some clientside config files........vs the configuration service.....you'll have to make that call.
But it sounds like you have a case of your client needing some cheese with their whine.
Here is an older video...that might get you on the right path.
http://channel9.msdn.com/Shows/Endpoint/endpointtv-High-Performance-WCF-NET-Stock-Trader-with-Greg-Leake
This PDF
http://download.microsoft.com/download/7/C/9/7C9F7B89-8AF0-4433-AB3A-B615C8EF9484/ConfigServiceVSTemplate.pdf
will give you the hints at it.
It is a lot of work to get a "configuration service" up and running.
We ended up...NOT doing it.......and using xml-manipulation in msbuild tasks.......to tweak the wcf client-side xml sections.
EDIT:
Alternate idea. Put you WCF in separate files..and distribute those.
It will make the "where to edit" much more discernable ..... or go with whole-sale replacement all of the (4) files.
app.config or web.config
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors configSource="WCFBehaviors.config">
</behaviors>
<bindings configSource="WCFBindings.config">
</bindings>
<client configSource="WCFClient.config">
</client>
<services configSource="WCFServices.config">
</services>
</system.serviceModel>
Then make the 4 files.
Example WCFServices.config
<services>
<service name="MyApp.MyService">
<endpoint
address = "http://localhost:8001/MyService"
binding = "wsHttpBinding" bindingConfiguration="WSHttpBindingName1"
contract = "MyApp.MyIService" >
</endpoint>
</service>
</services>
Note, these won't be auto-voodoo-included like web.config and app.config.
You'll have to make sure they end up in your build-outputs.
Unless you create a custom method to expose these parameters, or at least the values of them, they are not visible to the consumer.
Config files are supposed to be private which is why you are not able to browse to them in a standard installation.
It sounds to me like your client needs to accept that perhaps when adding a new service, there is a little bit of work that needs to be done. They could in theory cut and paste the servicemodel configuration, or sections of it, from an existing application to save 'some' time.
note: A github repo has been constructed to demonstrate the issue causing these questions.
In creating a WIF secured WCF service, the MSDN documentation recommends using the Identity and Access Tool for visual studio. Upon running the tool on the service project, the following node is added to the web.config [commit 0472287]:
<ws2007FederationHttpBinding>
<binding name="">
<security mode="Message">
<message>
<issuerMetadata address="https://localhost/adfs/services/trust/mex" />
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
The identity tool adds an incorrect issuerMetadata address and does not include the issure node at all. All of the nodes which reference certificate thumbprints are, thankfully, created correctly. Adding a service reference to a client project for this service results in an invalid configuration on the client. Upon changing the content of the message node as follows, creating a service reference to the service leaves a nearly usable client (see second question) [commit 758052d].
<message>
<issuer address="https://localhost:44300/issue/wstrust/mixed/username" binding="ws2007HttpBinding" bindingConfiguration="" />
<issuerMetadata address="https://localhost:44300/issue/wstrust/mex" />
</message>
First Question Is there something I am doing wrong in setting up the identity tool that is causing the binding to not be configured properly? The address that is generated does not exist in the STS FederationMetadata.xml file so I am not sure where it is coming from.
After properly configuring the service, the service reference for the client is nearly plug and play. For some reason, it doesn't specify a binding configuration for the issuer in the WS2007FederationHttpBinding. Adding a binding and creating a binding configuration for the WIF client to get a token from will cause the client to be in a working state [commit 39a4cbc].
Second Question Updating the service web.config allowed the rest of the client configuration to be generated automatically. Am I missing something for the client to also get the binding auto configured?
All of these missing elements are able to be looked up in the FederationMetadata.xml file the identity tool requires as well as on the FederationMetadata service which both projects become aware of. It seems that there should be something to cause these to be configured correctly without need of manual intervention.
note: A github repo has been constructed to demonstrate the issue causing these questions.
I am trying to add service reference.
There was an error downloading metadata from the address
this is the error which is being displayed again and again?
Please help
You may also just need to build / rebuild the project.
There are atleast 4 possibilities:
The metadata exchange mex endpoint is not defined
metadata exchange is not enabled
You are using the wrong address
You are being blocked by some security setting
Try the url in a browser to see that it returns a wsdl
It was happening the same to me and I found that I've had forgotten to add the "Service Contract" and the "Operation Contract" annotations on the interface of my WCF service
Just try to Build the project without any error and give service reference again.
In Web.config file I changed :
<endpoint address="" binding="pollingDuplexHttpBinding"
contract="IAsyncTaskService"/>
to this :
<endpoint address="" binding="pollingDuplexHttpBinding"
contract="DuplexService.Web.IAsyncTaskService"/>
and error was removed.
Zeni
Try rebuilding the project first, if that does not fix it, try changing the property httpGetEnabled from FALSE to TRUE in your web.config.
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
Check IIS is serving the service URL. In my case, I had changed my Windows password, but had forgotten that these credentials were being used by IIS in both the application and the app pool.
I know this is an oldie, but I thought I would add what worked for me so that I can find it again down the road ;)
In my case, the AppPool user didn't have access the %Windir%\temp, which apparently is necessary in order for the MEX data to be generated.
Shout out to Amy Peng in this thread for her tip!
Another possibility in this situation is that there is no endpoint listening. I.e., the service you are trying to add isn't "up". I made this mistake when trying to add a reference to a WCF service I was working on, but I forgot to Open it.
I had an issue like this one : Adding a service reference failed with a message "Method not allowed".
The wsdl worked fine in my browser..
The reason was that I configured the endpoint to listen on http://0.0.0.0:6000/mex, which the "Add Service Reference" tool doesn't seem to like. Changing it to a real IP address made it work (e.g. http://127.0.0.1:6000/mex)
Still hacking away with extreme persistence at WF services hosted outside of IIS. I'm now having issues with my WF service publishing metadata. Can someone take a look at my code and see what step I'm missing? The few tutorials that I've stumbled across for my scenario make it look so easy, and I know it is. I'm just missing something ridiculously simple. Here's my current trial code:
const string serviceUri = "http://localhost:9009/Subscribe";
WorkflowServiceHost host = new WorkflowServiceHost( new Subscribe(), new Uri(serviceUri) );
host.AddDefaultEndpoints( );
host.Open();
Subscribe() is an activity that is coded in an xaml file and contains simple receive and sendreply activities to test out my hosted workflow service. It is NOT a xamlx (WF service) file. Seems like this should be simple enough to work but when I start the application and the service fires I get this message in my browser when navigating to the URI:
"Metadata publishing for this service is currently disabled."
Shouldn't adding the default endpoints provide enough metadata and description to satisfy the service init and then go into its wait for message state?
For any future newbies, this also can be caused by not having your app.config setup correctly.
Add the below to your app.config and then open your service location in your browser:
<system.serviceModel>
<bindings />
<client />
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="True"
httpHelpPageEnabled="True"/>
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Well it appears that the debug instance process hung on my machine. I just used task manager to locate the executable and terminate the zombie process.