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

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.

Related

Passing a FileStream to WCF throws "Timeouts are not supported on this stream" exception

When trying to pass a small FileStream to my WCF service I get "Timeouts are not supported on this stream" error. Can anyone see what I'm doing wrong?
Interface:
[OperationContract]
List<SystemClass> ReadExcelFile(System.IO.FileStream stream);
Web.Config
<bindings>
<basicHttpBinding>
<binding name="streaming" maxReceivedMessageSize="2147483647" transferMode="Streamed">
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MISDashboard.wcfService" behaviorConfiguration="">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="streaming" contract="MISDashboard.wcfService"></endpoint>
</service>
</services>
...
<httpRuntime maxRequestLength="2147483647"/>
Do not use FileStream as parameter but Stream. A FileStream is a stream bound to the local file system; once you start transferring the data, in the other side the stream will be coming from the network, so a FileStream can't be used there.
You could believe it's pretty the same but Stream is treated in a special way by WCF and by-pass many internal tasks.
Also, for sending Large Data consider reading this great article.
I guess the issue over here is about the ReadTimeOut and WriteTimeOut properties. Under the hood WCF must be trying to set them up and as these are not implemented in FileStream class it throws the exception. So if you define the method Argument type as Stream WCF should create the appropriate stream that is required for data streaming. I would guess NetworkStream.

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

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:

WCF programmatically set endpoint address: No elements matching the key were found in the configuration element collection

I'm performing what I believed was a pretty basic task. We have an environment with multiple servers (DEV, TEST, PRODUCTION) and I'd like to programmatically change the service endpoint. To do this I am creating a new EndPointAddress and instantiating the client as:
BasicHttpBinding binding = new BasicHttpBinding("BasicHttpBinding_IMyService");
EndpointAddress endpoint = new EndpointAddress(new Uri("http://domain.name/myservice.svc"));
MyService.MyServiceClient client = new MyService.MyServiceClient(binding, endpoint);
I am receiving the following error.
No elements matching the key 'BasicHttpBinding_IMyService' were found in the configuration element collection.
I have included my app.config below but, as you can see, I do have the binding defined.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyService" >
<... removed directives for ease of reading ...>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://domain.name/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
contract="MyService.IMyService" name="BasicHttpBinding_IMyService" />
</client>
</system.serviceModel>
I'm sorry if this is a simple question but I haven't been able to identify the problem. I'll call it the 'late-Friday brain fog', and maybe you can call it 'easy points'?
Thanks!
The bindings in the Web.config of the WCF application and the app.config of the client application must match

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>

Custom MTOM Binding in WCF 4

Since WPF 4 provides default configuration out of the box, I'm having difficulty trying to create a custom MTOM binding for my service. In short, my WCF library hosts several services that are using basic HTTP. One of the services is used for file uploads and requires MTOM. What can I do so that only my file upload service uses a custom defined MTOM binding and the rest use the default?
This is what I have so far:
<bindings>
<basicHttpBinding>
<binding
name="FileTransferBinding"
transferMode="Streamed"
messageEncoding="Mtom"
maxBufferSize="65536"
maxReceivedMessageSize="10485760">
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="FileTransferService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="FileTransferBinding" contract="MyServices.IFileTransfer"/>
</service>
</services>
Thanks in advance!
In order to configure a service, the service name in the <service> element needs to be the type fully qualified name of the class implementing the service, in order to identify the service that is being configured administratively.
<service name="MyNamcespace.FileTransferService">
Service element MSDN:
Name : Required String attribute that
specifies the type of the service to
be instantiated. This setting must
equate to a valid type. The format
should be Namespace.Class.