My Experience with WCF
So this time I came across this issue
with WCF service which was hosted on IIS. The error that I was getting was
something like this,
System.InvalidOperationException:
General Error “http://mypublicwebserviceurl” ---> System.InvalidOperationException:
The document at the Url ‘http://mypublicwebserviceurl’ was not recognized as a
known document type.
The error message from each
known type may help you fix the problem:
- Report from
‘http://mypublicwebserviceurl’ 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://myinternalurl’.
- The remote name could not be resolved:
'hostname'
- Report from 'XML Schema'
is 'The document format is not recognized (the content type is 'text/html;
charset=UTF-8').'.
- Report from 'WSDL
Document' is 'The document format is not recognized (the content type is
'text/html; charset=UTF-8').'.
at System.Web.Services.Discovery.DiscoveryClientProtocol.DiscoverAny(String
url)
at
WebServiceStudio.Wsdl.ProcessRemoteUrls(DiscoveryClientProtocol client,
StringCollection urls, XmlSchemas schemas, ServiceDescriptionCollection
descriptions)
--- End of inner exception stack trace ---
at
WebServiceStudio.Wsdl.ProcessRemoteUrls(DiscoveryClientProtocol client,
StringCollection urls, XmlSchemas schemas, ServiceDescriptionCollection
descriptions)
at WebServiceStudio.Wsdl.Generate()
The service was working without any problem when used on the
machine where it was hosted. Problem started when I tried to access it with Public Web service URL outside of the server.
So here the problem was the URL shown in the address bar was different from one in WSDL soap:address and xsd:import schemaLocation.
Say my Public Web service URL is http://thisispublicurl:8888/myservice.svc
and in WSDL soap:address attribute URL is something like this.
<wsdl:service name="myservice">
<wsdl:port name="BasicHttpBinding_Imyservice" binding="tns:BasicHttpBinding_Imyservice">
<soap:address location="http://thisisinternalhostname:8888/myservice.svc”/>
</wsdl:port>
</wsdl:service>
Also schemaLocation in xsd:import is
something like this,
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://thisisinternalhostname:8888/myservice.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://thisisinternalhostname:8888/myservice.svc?xsd=xsd1"namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
</xsd:schema>
After hours of googling, I found several blogs saying write permission
should be given to application pool account user on %windir%/temp folder. But this didn't make any sense to me as my
service was running properly on server machine, but as I was desperate I tried
that too and it didn't work. Other thing that I came across was to add binding
in the IIS with the host-name. But that also didn't work. So then I started
looking at my app.config and comparing it with one provided by Microsoft. So
what I came across was my app.config don’t have <serviceHostingEnvironment
MultipleSiteBindingsEnabled="true" /> set.
So, I added this attribute and everything started working
properly. So when I googled what this element does and I came across this MSDN post https://msdn.microsoft.com/en-us/library/ee358763%28v=vs.110%29.aspx that explains “When hosting a Windows Communication
Foundation (WCF) service under Internet Information Services (IIS) 7.0, you may
want to provide multiple base addresses that use the same protocol on the same
site. This allows the same service to respond to a number of different URIs.
This is useful when you want to host a service that listens on
http://www.contoso.com and http://contoso.com. It is also useful to create a
service that has a base address for internal users and a separate base address
for external users. For example: http://internal.contoso.com and http://www.contoso.com.” And this explains what was wrong.
Thanks for reading.
Comments
Post a Comment