BACKGROUND
We have a WCF web service hosted in a Windows Service running with the basicHttpBinding.
PROBLEM
Browsing to the service URL on the local machine works fine, but trying to browse using the external IP address (either remotely or EVEN locally) does not work. Example:
http://localhost:8000/booking.svc (OK)
http://<external-IP>:8000/booking.svc (Not OK)
APP.CONFIG
<system.serviceModel>
<services>
<service behaviorConfiguration="DefaultServiceBehavior" name="HotelManagementSystem.ServiceHost.BookingService">
<endpoint address="" binding="basicHttpBinding" contract="HotelManagementSystem.ServiceHost.IBookingService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/booking.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Anyone have any ideas?
Try using useRequestHeadersForMetadataAddress
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<useRequestHeadersForMetadataAddress />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
This will allow the service to insert the URI you used to access the service in to the metadata so the wsdl aligns. Sometimes you'll go to access http://1.2.3.4/service.svc but the metadata will reference http://localhost. Locally that's fine, but remotely that makes grabbing the endpoint information impossible. Instead, now all those localhost references will use 1.2.3.4 instead.
Related
I have a running, mature WCF service that I am trying to deploy on Windows Azure as a Web Role (with a custom wrapper, of course). My RoleEntryPoint.OnStart() method creates a ServiceHost instance, where it trips with the zero application endpoints error. The configuration (web.config) service model section is:
<system.serviceModel>
<services>
<service name="Linguasys.QualitativeAnalysis.Processing" behaviorConfiguration="defaultServiceBehavior">
<endpoint address="" behaviorConfiguration="wcfAzureWrapperStoryMapping.StoryMapperAspNetAjaxBehavior" binding="webHttpBinding" contract="Linguasys.QualitativeAnalysis.IProcessing" />
<!--
<endpoint address="soap" behaviorConfiguration="" binding="basicHttpBinding" contract="Linguasys.QualitativeAnalysis.IProcessing" />
-->
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="wcfAzureWrapperStoryMapping.StoryMapperAspNetAjaxBehavior">
<!--
<enableWebScript />
-->
<webHttp faultExceptionEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<webHttpBinding></webHttpBinding>
<basicHttpBinding></basicHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<!--
<serviceActivations>
<add relativeAddress="StoryMapper.svc" service="Linguasys.QualitativeAnalysis.Processing"/>
</serviceActivations>
-->
</serviceHostingEnvironment>
</system.serviceModel>
Never mind the activation bits, the basic HTTP binding, etc. They were added later to see whether it will work.
I see that my web.config ends up at the siteroot and approot and all the other places.
What am I missing?
Your RoleEntryPoint.OnStart() method runs in WaIISHost.exe which does not know anything about your web.config. For more info see http://azure.microsoft.com/blog/2010/12/02/new-full-iis-capabilities-differences-from-hosted-web-core/, and for information about how the processes run see http://blogs.msdn.com/b/kwill/archive/2011/05/05/windows-azure-role-architecture.aspx.
Two options:
Move your WCF configuration to WebRole1.dll.config (or whatever your role entry point binary's name is). Make sure you set the .config to Content and copy local.
Instantiate your ServiceHost in w3wp (ie. Global.asax).
<system.serviceModel>
<services>
<service
name="myClass.IService1" behaviorConfiguration="myService">
<endpoint
name="ep1"
address="http://localhost:57582/Service1.svc"
contract="IService1"
binding="basicHttpBinding"
/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="myService">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
but still i am getting the following error::
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
your service name IService1 - this looks like it might in fact be
the contract. If you are using the normal templates then remove the
I from IService1
If you are IIS hosting you can remove the address as the location of the .svc file is automatically the address.
The contract needs to be fully qualified including the namespace of the contract interface
with this in place your metadata should be served from <.svc file location>?wsdl
I recently built a WCF Service, and now I'm deploying it to Windows Server 2008. Right now, we don't have secure protocol turned on. But we will. I'd like to get it working either way. In the site, I've had Anonymous authentication enabled as well as Forms authentication. The reason I did this was to prevent the authentication popup on the iPad, Android and Internet Explorer. So now they just get to the Login screen. Oh and I did activate WCF in Windows features. If you're also knowledgeable about making this https ready, I'd also like to figure that out. Thanks!!
I'm getting this error when I try pasting in the *.svc PATH into the URL.
System.ServiceModel.ServiceActivationException:
The service
'/WCFServices/Accessioning/QuickDataEntryService.svc'
cannot be activated due to an
exception during compilation
Here is my web.config configuration thus far.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<!--<baseAddressPrefixFilters>
<add prefix="http://localhost/" />
</baseAddressPrefixFilters>-->
</serviceHostingEnvironment>
<behaviors>
<endpointBehaviors>
<behavior name="AspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
</behavior>
<!-- Watch this section when adding a new WCF Service! New behaviors will be added; just delete them and use "ServiceBehavior" -->
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="A.LIMS.UI.Web.WCFServices.Accessioning.QuickDataEntryService">
<endpoint behaviorConfiguration="AspNetAjaxBehavior" binding="webHttpBinding"
contract="A.LIMS.UI.Web.WCFServices.Accessioning.QuickDataEntryService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
<!--<service name="A.LIMS.UI.Web.WCFServices.Accessioning.IQuickDataEntryService"
behaviorConfiguration="ServiceBehavior">
<endpoint behaviorConfiguration="AspNetAjaxBehavior"
binding="webHttpBinding"
contract="A.LIMS.UI.Web.WCFServices.Accessioning.IQuickDataEntryService" />
</service>-->
<!-- Watch this section when adding a new WCF Service! Duplicate the "QuickDataEntryService" above for an example, but change the fully qualified name -->
</services>
</system.serviceModel>
I have no clue what caused the exception above, but here was the final verdict. There were a lot of things required for WCF and using an SSL certificate (HTTPS protocol). Pardon the formatting.. I don't like how Stack Overflow sometimes puts the code into a block and sometimes it doesn't.
The following were required for the web.config on HTTPS:
Here are some places that required the "requireSSL" attribute:
<authentication mode="Forms">
<forms loginUrl="Login.aspx" timeout="30" protection="All" requireSSL="true" />
</authentication>
<httpCookies httpOnlyCookies="false" requireSSL="true" domain="" />
Notice the "s" in "httsGetEnabled" below:
<behaviors>
<endpointBehaviors>
<behavior name="AspNetAjaxBehavior">
<enableWebScript />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpsGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Bindings (missing in non-SSL web.config):
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>
Services (notice the "s" in "mexHttpsBinding"):
<services>
<service behaviorConfiguration="ServiceBehavior" name="A.LIMS.UI.Web.WCFServices.Accessioning.QuickDataEntryService">
<endpoint behaviorConfiguration="AspNetAjaxBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="A.LIMS.UI.Web.WCFServices.Accessioning.QuickDataEntryService" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
Last but not least. I'm not using .NET 4.0, but I did try .NET on a different machine. With .NET 4.0 I couldn't get the WCF services to work without having this configured to the actual URL being used. If there were two domains for the same IP, WCF only worked with the domain in this block inside the system.ServiceModel XML block in the web.config. I did not test https in the .NET 4.0, so I'm assuming the protocol on the URL would be https below:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://subdomain.domain.com/" />
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
Oh, I also had to turn on WCF on the Windows Server 2008 box. And it required a server reboot!
I host simple WCF service in IIS in web application.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="SimpleServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="SimpleServiceBehavior" name="SimpleService">
<endpoint address="" binding="basicHttpBinding" contract="ISimpleService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
When I run service hosted on http://projects.mydomain.com/application/SimpleService.svc it shows default service page with link to WSDL:
svcutil.exe http://terminal.mydomain.local/application/SimpleService.svc?wsdl and so on
Clients can create service reference but fail to execute methods because cannot resolve host name terminal.mydomain.local
The question is why server name is its local name 'terminal.mydomain.local' instead of 'projects.mydomain.com' ?
I found answer: http://forums.asp.net/p/1096811/1659596.aspx
I needed to change host headers.
using ASP.net, C#, IIS, jQuery
I have a wcf service running in iis on port 2515.
the demo i created for this project works fine and i can utilize the service.
I have another project running on port 2971.
I want this project to consume the wcf service via javascript but am getting a "method not allowed error".
Is this a cross-site scripting issue? I'm thinkin no since both projects are on the same domain but at different port numbers.
any help would be much appreciated.
<serviceBehaviors>
<behavior name = "MetadataBehavior">
<serviceMetadata httpGetEnabled = "true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="SandwichServices.CostServiceAspNetAjaxBehavior" >
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="SandwichServices.CostService" behaviorConfiguration="MetadataBehavior">
<endpoint address="" behaviorConfiguration="SandwichServices.CostServiceAspNetAjaxBehavior"
binding="webHttpBinding" contract="SandwichServices.CostService" />
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:2152/"/>
</baseAddresses>
If you're using XHR, the port is taken into account in the same-origin policy. You can't do requests across different ports - think of it as a part of the domain name.