问题
My apologize for long post... We have a WCF service written in .Net 4.0 used internally within the organization. Recently there was a requirement to make this service available outside the organization network. So the network guys used reverse proxy to make this service available outside the organization. Here is the picture how it is set up.
As you can see in the picture..the service http://mywebservice.com/readd.svc is hosted on WIndows 2008 R2 which has a internal IP address as XXX.YYY.ZZZ.RRR. The service is hosted on port 80.
what is the problem ?.
Internally I can access the service as http://mywebservice.com/readd.svc using WCFTestClient and browser. But outside the organization if I type http://mywebservice.com/readd.svc I get "404 file not find error" and in WCFTestCleint I get error as "Error: Cannot obtain Metadata from http://mywebservice.com/readd.svc .........".
However if I type in the service as in browser I get the screen which shows soap link as shown below. Please ignore the LookUpService.svc name mismatch.
As you can see in above figure ...address bar is https , but the soap link is http . If I click the http link http://.... ?wsdl , I get not found error. This is since Reverse proxy only allows connection as https .
If I use WCFTextClient and add servicie as https://mywebsite.com/readd.svc I get error as below.
"Error: Cannot obtain Metadata from https://mywebsite.com/readd.svc 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: http://mywebsite.com/readd.svc Metadata contains a reference that cannot be resolved:
'https://mywebsite.com/readd.svc'. Content Type application/soap+xml; charset=utf-8 was not supported
by service https://mywebsite.com/readd.svc.
The client and service bindings may be mismatched.
The remote server returned an error: (415) OK.HTTP GET Error
URI: https://mywebsite.com/readd.svc
The document at the url http://mywebsite.com/readd.svc 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 document format is not recognized (the content type is 'text/html; charset=UTF-8').'.-
Report from 'http://mywebsite.com/readd.svc' is
'The document format is not recognized (the content type is 'text/html; charset=UTF-8').'.-
Report from 'DISCO Document' is 'There was an error downloading 'http://mywebsite.com/readd.svc?disco'.'. -
The request failed with HTTP status 404: Not Found.- Report from 'WSDL Document' is 'The document format is not recognized (the content type is 'text/html; charset=UTF-8').'. "
I was informed by network guys to make service available as https. Here is my web.config file
<behaviors>
<serviceBehaviors>
<behavior name="ServiceLookup.LookupServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceLookup.LookupServiceBehavior" name="SmallApp.ServiceLookUp.LookUpService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BSBindingConfig" name="SmallApplianceBSEndPoint"
contract="SmallApp.ServiceLookUp.ILookupService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<!-- Remove this during deployment-->
<!--<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>-->
Can you suggest how I can resole this issue ..so that users outside organization can access the api with WCFTestCleint as http/https .
Updated web.config file
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceLookup.LookupServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceLookup.LookupServiceBehavior" name="SmallApp.ServiceLookUp.LookUpService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BSBindingConfig" name="SmallApplianceBSEndPoint"
contract="SmallApp.ServiceLookUp.ILookupService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<!-- Remove this during deployment-->
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
I am still gettign error accessing as http or https outside organization network
回答1:
The WSDL is typically generated on the fly based on your models metadata, attributes, and host location. So if the wsdl is then proxied to another environment, it's going to have issues.
One escape hatch in servicemetadata is to specify a externalMetadataLocation
:
A Uri that contains the location of a WSDL file, which is returned to the user in response to WSDL and MEX requests instead of the auto-generated WSDL.
Add externalMetadataLocation
like this below:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"
externalMetadataLocation="https://example.com/SOAP/Service1.wsdl" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
You can then pre-generate your WSDL ahead of time, tweak at will, and upload the modified file to serve as the contract.
Further Reading
- Supply a different endpoint address in the WSDL of a WCF web service
- WCF behind a public reverse proxy which is used for traffic encryption
- WebService behind reverse proxy
- WCF Webservice behind public reverse proxy
- Fix the Endpoint Address When Using externalMetadataLocation
来源:https://stackoverflow.com/questions/23435476/wcf-using-reverse-proxy