WCF WSDL generated paths for xsd:schema, wsdl:import, soap:address wrong for WCF behind a firewall.
My WCF server is behind a firewall
https://www.myserver.net/QA/WS?wsdl
but the schema locations are incorrect in the wsdl<xsd:schema targetNamespace="http://www.myserver.net/Imports">
<xsd:import schemaLocation="http://10.3.100.01:860/WS?xsd=xsd0" namespace="http://www.myserver.net" />
<xsd:import schemaLocation="http://10.3.100.01:860/WS?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xsd:import schemaLocation="http://10.3.100.01:860/WS?xsd=xsd2" namespace="http://www.myserver.net/" />
</xsd:schema>How do I change this to generate schemaLocation="https://www.myserver.net/QA/WS?xsd=xsd#" for all of these above.
I also have the same question for wsdl:import and soap:address.
<wsdl:import namespace="http://www.myserver.net" location="http://10.3.100.01:860/WS?wsdl=wsdl1" />
<soap:address location="http://localhost:860/WS/" />
Thanks for any info.
All Replies
You can setup your service to use a static wsdl with the correct addresses by using the ExternalMetadataLocation property on the ServiceMetadataBehavior.
Daniel Roth
When i set ExternalMetaDataLocation property on the ServiceMetaDataBehaviour to
http://(machineIP)/service1/service.svc?wsdl
When i test the service and click the link, page can not be found error is coming.
using the below also not working.
<
host><
baseAddresses><
add baseAddress=http://IPaddress/service1/service.svc /></
baseAddresses></
host>Can anyone help me how can i display ip address instead of machine name for the link to .svc wsdl while testing the WCF service?
Thanks in advance
- I have posted the same question, and I do not think there is a way to do that - hopefully Microsoft will implement this shortly (ie., an additional parameter to the .svc file, specifying a domain name to be used instead of the machine name). I was forced to set the ExternalMetaDataLocation property to a static wsdl, and also create the xsd files and put all files in the virtual directory for the web service. The reason you have to create the xsd file(s), is the .svc file that generates these files is not correct due to the machine name thing. I was able to create the xsd file(s) by hitting the link in the wsdl (...?xsd) on my browser and saving the file to disk.
Thanks for your reply. Can you suggest me the file name and extension to be used for xsd files to save in the virtual directory folder? Do we need to save the wsdl file also? Any changes required (like schema url) in xsd or wsdl while saving?
Can you provide me the steps required to do this?
--Thanks
1) Produce the wsdl in the browser and save to file (by hitting .svc?wsdl from browser)
2) Produce the xsd files by hitting url from wsdl (xsd=xsd0, etc), and save to file from browser
3) replace all machine name references from wsdl with domain name (or ip address) and change xsd references and save
4) replace all machine name references from xsd files with domain name (or ip address)
5) make sure to name xsd file with .xsd extension (ie, name_0.xsd, name_1.xsd)
6) copy wsdl and xsd file(s) to virtual directory
7) add the following entry in your web.config file:
<behaviors>
<serviceBehaviors>
<behavior name="CallRoutingBehavior">
<serviceMetadata httpsGetEnabled="true" externalMetadataLocation="https://vconsole.virtualpbx.com/callrouting/callrouting.wsdl"/>
</behavior>
</serviceBehaviors>
</behaviors>- ...or just run disco.exe on the ?wsdl and it downloads it all and then tweak it.
Thanks alot. It is working. Sometimes while adding service reference, i m getting error like
Cannot find file "C:\Documents and Settings\padmajab\Local Settings\Temp\23hzb1ps.ym5\Service1.cs".
Service.cs is my WCF service class.
When i give
externalMetadataLocation
=http://IPaddress/Services/Service1.svc,i am getting the error as
Cannot find file "C:\Documents and Settings\padmajab\Local Settings\Temp\23hzb1ps.ym5\Service1.cs".
When i use externalMetadataLocation = http://IPaddress/Services/Service1.wsdl , everything is working perfect.
Thank you so much.
create the cs file by calling svcutil and passing the wsdl as the parameter, or you can try add web reference instead of add reference.
Your welcome,
John Shore
Can you tell how you have configured the service in .config file to get the wsdl and xsd's with IP address.
My problem is exactly opposite to you. I need to create wsdl and xsd with url includes ip like your created files. My wsdl and xsd's got created refering the machine name by default when i click file.svc?wsdl in service test page.
Can you help me?
You have to follow these steps:
1) Produce the wsdl in the browser and save to file (by hitting .svc?wsdl from browser)
2) Produce the xsd files by hitting url from wsdl (xsd=xsd0, etc), and save to file from browser
3) replace all machine name references from wsdl with ip address and change xsd references and save
4) replace all machine name references from xsd files with ip address
5) make sure to name xsd file with .xsd extension (ie, name_0.xsd, name_1.xsd)
6) copy wsdl and xsd file(s) to virtual directory
7) add the following entry in your web.config file:
<behaviors>
<serviceBehaviors>
<behavior name="CallRoutingBehavior">
<serviceMetadata httpsGetEnabled="true" externalMetadataLocation="https://vconsole.virtualpbx.com/callrouting/callrouting.wsdl"/>
</behavior>
</serviceBehaviors>
</behaviors>Currently, this is the only way to produce a wsdl and xsd file(s) from the svc file using something other than the machine name. I have asked Christian Weyer to bring this issue up with Microsoft, and I have given him source code to demonstrate.
I have something similar I believe. Here is our situation:
We have a development server named DVL01. For each project we create a new web site and a DNS entry on our DNS server that points to that website.
For each project we also create a new Application Pool and a new service account in the Active Directory that will be used to set the security context of the application pool.
Next we create a Service Principal Name (SPN) in the Active Directory so that this service account can only be used in a specific correct context.
Eg:
We have a project called ProjectX. When we navigate to http://ProjectXDVL:9501 it will be resolved to http://DVL01:9501. Navigating directly to http://DVL01:9501 gives a 401 (unauthorised) which is exactly what we want, that is the SPN kicking in. The problem now is that in the WSDL the schemaLocation for the XSD's point to http://DVL01:9501/EmployeeService.svc?xsd=xsd0 and this gives a 401 (again SPN). The correct URI should be http://ProjectXDVL:9501/EmployeeService.svc?xsd=xsd0.
I have tried chaning the host header value, I have also tried adding a baseAddress in the web.config but nothing seems to help.
Are you trying to say that this is not possible by configuration?
All you need to do is set the default host header name for that site. For example, I needed to use adsutil.vbs to set the default header for our https site. Once I did this, the computer name was replaced by the domain name in the links for the schemas.
- I already tried that but that doesn't change the uri of the schemaLocation it still points to http://DVL01 instead of http://ProjectXDVL
- Anyone know if anything has been done to resolve this problem?
- I can't find any way to fix this, I've spent the day going crazy over this stupid rediculous issue. How can they not view this as an issue that needs to be fixed? ARGH!!
All you need to do is set the default host header name for that site. For example, I needed to use adsutil.vbs to set the default header for our https site. Once I did this, the computer name was replaced by the domain name in the links for the schemas.
Also, you have to open up the security to c:\windows\temp since this is where WCF creates the temp files.
jvshore, not sure your solution will work for a self hosted (ie outside if IIS) WCF service behind a firewall.
Bottom line there should be a in code and config file way to set what gets generated in the wsdl at runtime, all the comments about generating the wsdl and tweak the content are defeating the whole purpose of interop with wsdls.
I'm glad I found this thread...I've been pulling my hair out for several days trying to figure this out. I believe I'm having the same problem as others here. I finally had a little time to start looking at WCF and I had put together a test service. It worked fine on my dev machine, but once I put it on a server, it will only generate the wsdl with the machine name.
Doesn't matter what I specify for the endpoint address, or the dns identity value, etc...it won't use the IP or domain...it just keeps using the machine name for the wsdl. This is going to be extremely problematic. I guess I can stop wasting my time trying to figure out what the problem is though, and just wait until this is resolved before doing any more WCF stuff.
Not sure why it refuses to honor what I specify in the web.config file.
-Matt
Matt, you may be waiting a long time, I opened this thread going on two years now, well in the beta feedback time before the first RTM release of WCF in .net 3.0. MS did not seem to answer my post or change the code, but I have not tried it on the 3.5.
I have deployed and support many WCF in a production environment today, and the only practical way we have found to deploy it is:
Firewall->Proxy Server->Internal WCF Service.
The proxy server handles the https certificate and also does a search and replace on the internal url with the external on WCF responses, and external url with internal on client WCF request.
Sample
Client- Request -> https://www.myserver.net/QA/WS?wsdl -> Proxy -> http://10.3.100.01:860/WS?wsdl WCF
Client- Response <- https://www.myserver.net/QA/WS?wsdl <- Proxy <- http://10.3.100.01:860/WS?wsdl WCF
The setup works with WSDL client generation, and all request and response traffic.
Just make sure you have the proxy translate all the url lines that are incorrect.
Just info for others incase they want to get going today with WCF, while we wait for an elegant incode solution.
ACHawk
Hello,
I have exactly the same issue. Addresses which are generated in the links for the schemas are not correct.
In order to solve it, I wanted to try the solution of jvshore but could you please describe me how to set the deault host header? I don't have access to my IIS, so I cannot configure it.
Thanks in advance,
Jerome.
I used adsutil.vbs from inetpub\adminscripts:
cscript.exe adsutil.vbs set /w3svc/<site identifier>/SecureBindings ":443:<host header>"
This script set the host header for me for SSL, which you can't do from the UI. You can also set the host header for a site without referring to SSL using this command.
You also have to make sure that you have rights to c:\windows\temp. WCF uses this directory to create the schemas that are generated. If you do not set access rights to this directory, the WSDL will appear correct with the appropriate addresses for the schemas, but the schemas will not be created.
Hope this helps. I spent several weeks with this problem before I got the Microsoft engineers to view the debug files that showed the problem. Now everything is working great.
So, by setting the host header, WCF wsdl generation work behind the firewall?
- I think I have found a solution to these incorrect schemaLoction url values when the site is controled by a load balencer or firewall. The solution is not fully tested, but appears to work for me so far. You want to open Internet Information Services (IIS) Manager then locate your web. Right click on the web site and go to properties. In the web site properties window select the "Web Site" tab and click on the "Advanced..." button in the "Web site identification" section. Now select your ip address from the "Multiple identities for this Web site" and click "Edit...". This will open the "Add/Edit Web Site Identification" window. You will want to enter the url of your site in the "Host Header value:" textbox. It should be something like www.yourwebsitedomain.com. Click "OK" out of all the windows then do an iisreset. This appeared to fix the problem for me.
Ryan Means wrote: I think I have found a solution to these incorrect schemaLoction url values when the site is controled by a load balencer or firewall. The solution is not fully tested, but appears to work for me so far. You want to open Internet Information Services (IIS) Manager then locate your web. Right click on the web site and go to properties. In the web site properties window select the "Web Site" tab and click on the "Advanced..." button in the "Web site identification" section. Now select your ip address from the "Multiple identities for this Web site" and click "Edit...". This will open the "Add/Edit Web Site Identification" window. You will want to enter the url of your site in the "Host Header value:" textbox. It should be something like www.yourwebsitedomain.com. Click "OK" out of all the windows then do an iisreset. This appeared to fix the problem for me. This does not work for SSL sites.
Nor does it work for self hosted WCF solutions which is how this original post was opened ******y me.
******ut MS did not seem to care in their ******eta cycle or now, if anyone has any contacts in the WCF development team may******e they can help on this one.
AC
ACHawk wrote: Nor does it work for self hosted WCF solutions which is how this original post was opened ******y me.
******ut MS did not seem to care in their ******eta cycle or now, if anyone has any contacts in the WCF development team may******e they can help on this one.
AC
1) apparently the html editor on these forums has a bug. Seeing a lot of ******* inserted in text.
2) My admin freaked when I discussed the host headers solution above, so I am going to investigate the static WSDL (YUK).
3) I'm interested in your problem (service host) as I'm sure I'll eventually want to do the same.
&n******sp;jvshore wrote: You have to follow these steps:
&n******sp;
1) Produce the wsdl in the ******rowser and save to file (******y hitting .svc?wsdl from ******rowser)
2) Produce the xsd files ******y hitting url from wsdl (xsd=xsd0, etc), and save to file from ******rowser
3) replace all machine name references from wsdl with ip address and change xsd references&n******sp;and save
4) replace all machine name references from xsd files with ip address
5) make sure to name xsd file with .xsd extension (ie, name_0.xsd, name_1.xsd)
6) copy wsdl and xsd file(s) to virtual directory
7) add the following entry in your we******.config file:
&n******sp;
<******ehaviors>&n******sp; <service******ehaviors>&n******sp;&n******sp;&n******sp;&n******sp;<******ehavior name="CallRouting******ehavior">&n******sp;&n******sp;&n******sp;&n******sp;&n******sp;&n******sp;<serviceMetadata httpsGetEna******led="true" externalMetadataLocation="https://vconsole.virtualp******x.com/callrouting/callrouting.wsdl"/>&n******sp;&n******sp;&n******sp;&n******sp;</******ehavior>&n******sp;&n******sp;</service******ehaviors></******ehaviors>
Currently, this is the only way to produce a wsdl and xsd file(s) from the svc file using something other than the machine name. I have asked Christian Weyer to ******ring this issue up with Microsoft, and I have given him source code to demonstrate.
&n******sp;
(Man, I swear there are pro******lems with the editor today. I can't get it to respect the end quote. Yikes!)
&n******sp;
To ******e clear, when you change the reference, you change them from
"...service.svc?xsd=xsd0" to "...service_0.xsd" using your technique?
&n******sp;
&n******sp;
Here is the solution that worked for me (thank you Amy at MS!):
1) Implement the Factory attribute to specify the custom ServiceHost in the .svc file:
<% @ServiceHost Language=C# Debug="true" Factory="HelloServiceFactory" Service="HelloService" CodeBehind="~/App_Code/HelloService.cs" %>
2) Create the ServiceFactory “HelloServiceFactory” class as follows:
class HelloServiceFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
HelloServiceHost customServiceHost = new HelloServiceHost(serviceType, baseAddresses);
return customServiceHost;
}
}
class HelloServiceHost : ServiceHost
{
public HelloServiceHost(Type serviceType, params Uri[] baseAddresses)
: base(serviceType, GetBaseAddresses())
{ }
protected override void ApplyConfiguration()
{
base.ApplyConfiguration();
}
// read base addresses from AppSettings in config
private static Uri[] GetBaseAddresses()
{
List<Uri> addresses = new List<Uri>();
AddBaseAddress(addresses, "baseHttpAddress");
return addresses.ToArray();
}
private static void AddBaseAddress(List<Uri> addresses, string key)
{
string address = ConfigurationManager.AppSettings[key];
if (null != address)
addresses.Add(new Uri(address));
}
}
3) Add the baseHttpAddress to the web.config:
<configuration>
<appSettings>
<add key ="baseHttpAddress" value="<<http://www.domain.com/HelloService.svc>>" />
</appSettings>
</configuration>
- Proposed As Answer byRailgun Thursday, December 11, 2008 5:08 PM
I followed these steps, looks like the wsdl and xsd files are generated with proper references, but the disco file still references internal server name. Is there a way to specify server name in disco file. I manually changed the disco file on our server but I am not sure how to refernce it in web.config.
Please respond if you had the same issue and resolved it.
WOW, I racked my brains out for days too with this same problem. I was starting to get embarrased about suggesting we write services in WCF. My situtation is a WCF service hosted in IIS on a server via HTTPS/SSL but HTTP is turned off. Worked fine on development servers, but as soon as we moved it out to the above setup, none of the clients could resolve the location of the opeations.
At first I thought it was because the server had a self-signed certificate, so we got a legit one. Only helped a little in that then wcftestclient worked fine but none of the ColdFusion or Flex clients would work.
In our environment there is no way to get the admins to add the host header to an SSL site - "hey, can you run this script you've never heard of on a production server hosting dozens of apps all written in different languages." Yea right.
I was about to punt and just re-write the services in ColdFusion or PHP since there seemed to be no way to get the location to match the domain name instead of the machine name by setting something in web.config. Seems really silly.
The static WSDL seemed like a last resort so I tried the Service Host Factory and that worked. I'm not happy about having a var that has to be set for the service outside the service section of config but...Also funny that the ServiceHost directive in the .svc does not recognize factory attribute in intellisense, but yet it works. Remeber to preface the service host factory class name with its namespace
Factory="MyNampeSpace.MyHostFactory"
Yea, this needs to be fixed.- Edited byRailgun Thursday, December 11, 2008 3:20 PMsp
This solution worked for us! We were rattling our brains on this one for several hours! Thank you!
- All you have to do is make sure that your host headers have been setup properly in your IIS site. This may have to be done via the IIS Metabase or using the following command line. There are 2 bindings which need to be updated depending on whether you need SSL or not.
adsutil.vbs set W3SVC/1/ServerBindings “:80:www.fancydomain.com”
adsutil.vbs set W3SVC/1/SecureBindings “:443:www.fancydomain.com”
http://blogs.msdn.com/wenlong/archive/2007/08/02/how-to-change-hostname-in-wsdl-of-an-iis-hosted-service.aspx I also had problems with the URLs generated in the WSDL
I fixed this by modifying the webconfig and hardcoding the WSDL path like so (path for the authentication service (yes I will move it to https)):<serviceBehaviors> <behavior name="AuthenticationServiceTypeBehaviors"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://<sitename>/Services/Authentication.svc/wsdl"/> </behavior> </serviceBehaviors>
Hopefully this will save you some time.
Miro- I noticed that this is an old post. But I came across this recently and followed the solution that was provided and still had some issues. the short of it is that i found the solution here http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/c8d5b303-a58f-4d60-bf84-baf01bc71092/so i thought I would share this.

