WCF - Cannot obtain Metadata, but works when the XML Endpoint is removed? - wcf

I'm having a problem with the WCF Test Client. I cannot connect to my WebService because it keeps hitting this error:
Error: Cannot obtain Metadata from
http://xxx.xxxxxxxx.xxx/DPITerminal.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://xxx.xxxxxxxx.xxx/DPITerminal.svc
Metadata contains a reference that cannot be resolved:
'http://xxx.xxxxxxxx.xxx/DPITerminal.svc'. Content Type
application/soap+xml; charset=utf-8 was not supported by service
http://xxx.xxxxxxxx.xxx/DPITerminal.svc. The client and
service bindings may be mismatched. The remote server returned an
error: (415) Cannot process the message because the content type
'application/soap+xml; charset=utf-8' was not the expected type
'text/xml; charset=utf-8'..HTTP GET Error URI:
http://xxx.xxxxxxxx.xxx/DPITerminal.svc There was an error
downloading 'http://xxx.xxxxxxxx.xxx/DPITerminal.svc'.
Here is my Web.Config: Link.
As you can see, I already have the
<serviceMetadata httpGetEnabled="true" />
as well as
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="mex" contract="IMetadataExchange" />
as suggested in the other StackOverflow questions. Still doesn't work.
I also noticed that when I comment the following endpoint:
<endpoint address="x" behaviorConfiguration="poxBehavior" binding="webHttpBinding" bindingConfiguration="web" contract="xxx.xxxxxxxx.xxxxxx.WebService.IDPITerminal" />
Everything works as expected. So I guess there's a problem with my XML Endpoint? It's weird since the XML Endpoint is sharing the JSON Endpoint's binding configuration, and the JSON one doesn't have any problems.
Also, Let me clarify that I'm only having problems with the WCF Test Client. The JSON & the XML Endpoint is both working properly.
EDIT:
I tried to comment the XML Endpoint, publish, then connect via the WCF Test Client. Then I uncommented the XML Endpoint, republish. The WCF Test Client still works- I mean I can send and receive data. When I refreshed the service, the Cannot obtain Metadata error popped out again.

It seems that WCF does not allow to use the same configuration for 2 endpoints.
There is workaround to fix the issue:
Change bindingConfiguration attribute for endpoint address="x" from web to web2
Add new web2 webHttpBinding configuration (copy web configuration):
Code for new binding configuration:
<webHttpBinding>
<binding name="web" ... />
<binding name="web2" closeTimeout="00:10:00" openTimeout="00:10:00"
sendTimeout="00:10:00" allowCookies="true" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="8192" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</webHttpBinding>
Update:
WCF Test Client is not able to obtain metadata for webHttpBinding because such metadata does not exist. RESTfull service does not support WSDL or similar protocol that is used for basicHttpBinding or wsHttpBinding. Service returns error when WCF Test Client tries to get metadata in both cases (when WCF Test Client fails and when not) but for some reason in case of proposed workaround WCF Test Client manages to swallow error. It is hard to say why without WCF Test Client source codes.
Error in Trace Viewer:

Related

How do I set the proxy in webhttpbinding configuration to use fiddler

I'm trying to setup my Web service client to use fiddler proxy by setting it in the webhttpbinding configuration file as follows:
<bindings>
<webHttpBinding>
<binding name="RestBinding" proxyAddress="http://localhost:8888"
useDefaultWebProxy="false">
</binding>
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:2172/RestServiceImpl.svc"
binding="webHttpBinding" behaviorConfiguration="RestService"
bindingConfiguration="RestBinding"
contract="IWS.IRestServiceImpl" name="Rest"/>
</client>
This doesn't seem to work. I don't see anything logged in fiddler when calling the webservice from the client. I know the call is being made because I get a response back from the service.
I can't seem to figure out what I'm doing wrong.
Any help is appreciated!
Thanks!!
The .NET Framework does not send requests for "localhost" to any proxy, including Fiddler. To workaround this, try to use your machine name instead as the endpoint address (e.g. http://mymachine:2172/RestServiceImpl.svc).
Also, take a look on Using Fiddler with IIS7 Express

UsernameToken and SSL in WCF 4 web service - but with basicHttpBinding

A few months ago I asked about UsernameToken and SSL in WCF 4 web service and received a good answer using wsHttpBinding.
However now we have had to revert to using basicHttpBinding due to incompatibilities with a Java client. I've tried switching the configuration as follows....
<bindings>
<basicHttpBinding>
<binding name="secureBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
And then using this config in the service...
<service name="ServiceName">
<endpoint binding="basicHttpBinding" bindingConfiguration="secureBinding" contract="ContractType" />
</service>
However when I try to make a call to this service I am getting back an error...
The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: via
Is there something else I need to configure to make this work with basicHttpBinding?
(Please note: My original requirements are still the same - SSL, usernametoken)
As per my comments (below the original question) this was actually a problem when using WCFStorm as the client.
The solution to this was found as one of the answers on this question The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via
This was to click on the "Config" settings option (NOT THE "Client Config") in WCFStorm. After clicking on that, click on the "Security" tab on the dialog that pops up. Make sure "Authentication Type" is set to "None" (The default is "Windows Authentication").

WCF service hosted in IIS 7 - binding configuration settings are ignored

I have a WCF service operation that accepts a byte array as part of its data contract. The service is only exposed internally (not to the internet), and I want to increase the quotas to allow for a 10MB byte array.
The service is hosted in IIS7. When I try to send a byte array over the default length, I get the following exception message:
There was an error deserializing the object of type
MyService.ServiceContracts.Data. The maximum array length quota
(16384) has been exceeded while reading XML data. This quota may be
increased by changing the MaxArrayLength property on the
XmlDictionaryReaderQuotas object used when creating the XML reader.
Line 1, position 22991.
Here's the configuration:
<system.serviceModel>
<netTcpBinding>
<binding name="largeBinaryBinding" maxReceivedMessageSize="10001000"
maxBufferPoolSize="80008000" maxBufferSize="10001000"
receiveTimeout="00:01:00" openTimeout="00:01:00"
closeTimeout="00:01:00" sendTimeout="00:01:00">
<readerQuotas maxArrayLength="10000000" />
</binding>
</netTcpBinding>
<services>
<service name="MyService">
<endpoint binding="netTcpBinding"
bindingConfiguration="largeBinaryBinding"
bindingNamespace="http://my.services.co.uk/MyService"
contract="Services.MyService.ServiceContracts.IMyService" />
</service>
</services>
</system.serviceModel>
So my configuration allows for larger messages, but IIS seems to be ignoring this - how do I stop this and allow large messages through?
Again, just after I post a question I discover the answer!
When using WAS, you need to specify the full class name of the service in the configuration's service name. So in my example, I had my service implementation class called MyService, in the namespace Services. Therefore, in the configuration, I need
<service name="Services.MyService">
...
Otherwise IIS silently ignores your carefully crafted configuration! How convenient.

How to set up bindings in webconfig to enable streaming in RESTful WCF service

I have a RESTful service which I'm trying to enable to accept a PDF file. I'm using a stream to transport it, but I keep running into mysterious errors in the process.
My first error is this: Security negotiation failed because the remote party did not send back a reply in a timely manner. This may be because the underlying transport connection was aborted.
Not sure what's causing that. Also, I tried adding a customBinding in an attempt to fix this error, and I get an error that says I don't have my binding set up properly.
My main, overall question is this:
Does anyone know of a simple binding and complete instructions for how to set it up to enable streaming?
I managed to get it working. I found that my problem wasn't my binding, but that it was never registered. Here's the code in the web.config file:
<services>
<service name="ResearchUploadService.Service1" behaviorConfiguration="ResearchUploadService.Service1Behavior">
<endpoint address="" binding="customBinding" bindingConfiguration="basicConfig" contract="ResearchUploadService.IService1"/>
</service>
</services>
...
<bindings>
<customBinding>
<binding name="basicConfig">
<binaryMessageEncoding/>
<httpTransport transferMode="Streamed" maxReceivedMessageSize="67108864"/>
</binding>
</customBinding>
</bindings>

WCF Security - how to allow all callers to this url?

I have a WCF service self-hosted in a windows service environment that works fine over http; over https I am unable to get to one URL without seeing the windows login prompt when running the silverlight application (or just opening the page in IE). I am using the IPolicyRetriever interface to ensure that the ClientAccessPolicy.xml file is found for the Silverlight app. This is working correctly.
The service in question has two endpoints defined:
<service behaviorConfiguration="defaultBehavior" name="WCFServices.Scheduler">
<endpoint address="WCFServices/Scheduler/" binding="wsHttpBinding" bindingConfiguration="dBinding" contract="WCFServices.IScheduler" />
<endpoint address="" binding="webHttpBinding" contract="WCFServices.IPolicyRetriever" behaviorConfiguration="PolicyBehavior" bindingConfiguration="dBinding" />
<host>
<baseAddresses>
<add baseAddress="https://myservername.org/" />
</baseAddresses>
</host>
</service>
If I go to the https://myservername.org/ I see the test service frontend (with a link to the wsdl). This is exposing the root IPolicyRetriever instance that the Silverlight app uses to pull down the policy file. I can load this and other URLs that expose the WCF service without any login prompts. BUT if I go to https://myservername.org/WCFServices/Scheduler/ in IE 8 I am greeted with a windows login. If I reset the security settings on the service and client to use http, I am able to do go to the latter url without the login prompt, and the silverlight app functions as expected. I suspect it has something to do with this WCF service being the only one with two endpoints defined (this windows service hosts 5 other WCF services, all of which only have 1 endpoint defined). Am I missing some authorization rules? I don't understand how that can be because all the other services load without prompts.
I would appreciate any help. I need the full https://myservername.org/WCFServices/Scheduler/ to serve the WCF service without asking for a login. Thanks for taking the time to read this.
As far as security, I only have this as my binding:
<binding name="dBinding" maxBufferPoolSize="524288" maxReceivedMessageSize="6553600">
<security mode="Transport">
</security>
</binding>
This issue was resolved by adding these lines to my security binding:
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"/>
</security>
...but that led to a host of other issues, all of which I've been able to handle thanks to WCF logging. If you run into a NOT FOUND (400) error when debugging your WCF service, don't believe it. Turn on server side debugging and pour through the generated log files -- you'll get to the bottom of it.
I should also note that I've found the second endpoint to return a bad request (400) when opening in a web browser, and this is BY DESIGN. The first endpoint will list all additional endpoints in its wsdl, and you can still use any of them in a proxy generating tool. Don't worry if you're getting a bad request error when trying to access them directly in a browser.