WCF Rest Service with both http and https bindings - asp.net

I'm trying to create a rest service that can accept both http and https traffic. The reason for this is that my company offers our customers both a hosted and non-hosted solution. In the hosted solution, all traffic goes through an F5 which strips out the SSL and forwards it to our servers in regular http.
The non-hosted solutions have their web servers handle the SSL (thus, the server is expecting https security).
The binding was originally defined like so:
<webHttpBinding>
<binding closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
</security>
</binding>
</webHttpBinding>
However, this did not work for our non-hosted customers. I then changed it to this
<webHttpBinding>
<binding closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
</security>
</binding>
</webHttpBinding>
But, as you can guess, this did not work for our hosted customers.
Is it possible to have a WCF rest service using the .NET 4.0 framework accept both http and https traffic?
I have tried this:
<webHttpBinding>
<binding name="normalRestBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
</security>
</binding>
<binding name="secureRestBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
</security>
</binding>
</webHttpBinding>
with this service definition:
<service name="theService" behaviorConfiguration="RestServiceBehavior">
<endpoint name="normalRestEndpoint" address="" behaviorConfiguration="RestEndpoint" binding="webHttpBinding" bindingConfiguration="normalRestBinding" contract="theContract">
<identity>
<dns />
</identity>
</endpoint>
<endpoint name="secureRestEndpoint" address="" behaviorConfiguration="RestEndpoint" binding="webHttpBinding" bindingConfiguration="secureRestBinding" contract="theContract">
<identity>
<dns />
</identity>
</endpoint>
</service>
Using these, I am now getting this error when trying to access the endpoint over regular http:
Could not find a base address that matches scheme https for the endpoint with binding WebHttpBinding. Registered base address schemes are [http].
Any help would be greatly appreciated.
Thanks!

Was able to figure this out.
The code I put toward the bottom of the questions was fine.
To resolve that error message, I had to ensure that an https binding existed in IIS on the server(s) I was attempting to use this web config for.
Sorry for self-answering, but I didn't want to leave this open and somebody waste their time trying to answer it for me!
Thanks!

Related

The maximum message size quota for incoming messages (33554431) has been exceeded

My client application is calling a web service, everything works fine, except a function call always throw this error (The maximum message size quota for incoming messages (33554431) has been exceeded.)
I have tried to increase the maxBufferSize in the app.config file of my client application to 335544310, but it did not help solving this problem.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpsEndpoint" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard" maxBufferSize="33554431" maxBufferPoolSize="33554431" maxReceivedMessageSize="33554431" messageEncoding="Text" textEncoding="utf-8"
transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="33554431" maxArrayLength="33554431" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://api.smartmailpro.com/2.0/API.svc" binding="basicHttpBinding" bindingConfiguration="basicHttpsEndpoint" contract="SmartMailProApi.API" name="basicHttpsEndpoint" />
</client>
</system.serviceModel>
I suspect that there are two possibilities
1) The value that I am using is too large
2) I need to perform the same update to the server web services as well
Could anyone point me to the right direction, please?
What are the real purposes of following three parameters :
maxBufferSize="33554431"
maxBufferPoolSize="33554431"
maxReceivedMessageSize="33554431"
Enlarge the value of the maxBufferSize to 2147483647, and solved the problem.

WCF Error because The maximum message size quota for incoming messages (65536) has been exceeded

i make WCF service on server side to return binary (bytes) of file..
i just can return binary of txt file,otherwise it's say "The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element."
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
transferMode="Buffered"
messageEncoding="Text"
textEncoding="utf-8"
bypassProxyOnLocal="false"
useDefaultWebProxy="true" >
<security mode="None" />
<readerQuotas maxDepth="2147483647"
maxArrayLength="2147483647"
maxStringContentLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
can you give me solution?
i need your help..thanks before :)
here is client code side (app.config)
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:3724/Service.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService"
contract="ServiceReference1.IService"
name="BasicHttpBinding_IService" />
</client>
this client is desktop application not website
You need to assign the binding you defined to an endpoint you create. Here's an example:
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
transferMode="Buffered"
messageEncoding="Text"
textEncoding="utf-8"
bypassProxyOnLocal="false"
useDefaultWebProxy="true" >
<security mode="None" />
<readerQuotas maxDepth="2147483647"
maxArrayLength="2147483647"
maxStringContentLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service>
<endpoint address="/Service.svc" binding="basicHttpBinding"
bindingCongifuration="basicHttp"
contract="service.IService"/>
</service>
</services>
A couple of things to note - in your comment, your service endpoint was using wsHttpBinding, but you defined basicHttpBinding in your <bindings> section. Also, the bindingConfiguration attribute must be the name assigned to the binding defined. My example above is based on the original posted config file.
Alternatively, if you are using .NET 4.0 or later, you can define a binding in the <bindings> setting and set it as the default definition for that binding by omitting the name attribute on the <binding> element.
By default, .NET 4.0+ uses basicHttpBinding for http. You can change this in the config file in the <protocolMapping> section (which is contained in the <system.serviceModel> section). For example, if you wanted to use wsHttpBinding for all http requests, you would do this:
<protocolMapping>
<add binding="wsHttpBinding" scheme="http" />
</protocolMapping>
Added Client Example
The client side would look very similar, except you'd have a <clients> section instead of a <services> section. Note that some of the settings on the binding apply to the machine (client or server) the application is on, and setting them on one side of the client-server relationship will have no effect on the other side (like maxReceivedMessageSize, for example). Generally the binding type and security have to agree, and in practice it's usually easier to just use the same bindings on both ends, but it is possible to have a scenario where one side would have different buffers or other items.
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" allowCookies="true"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
transferMode="Buffered"
messageEncoding="Text"
textEncoding="utf-8"
bypassProxyOnLocal="false"
useDefaultWebProxy="true" >
<security mode="None" />
<readerQuotas maxDepth="2147483647"
maxArrayLength="2147483647"
maxStringContentLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="localhost:3724/Service.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService"
contract="ServiceReference1.IService"
name="BasicHttpBinding_IService" />
</client>

Slowing web application with WCF on timely request

I am new for the WCF, i have web application which uses WCF Service as a data access layer. I am using wcf service library and hosterd it on IIS7. It works fine for few initial service calls but hangs an application for further request. When i reset IIS , then again it is working fine for some time.
Below is the service configuration in web.config of web app
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IRoaster" closeTimeout="00:10:00"
openTimeout="00:01:00" receiveTimeout="00:02:00" sendTimeout="00:03:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="199999488" messageEncoding="Text"
textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://asdf.com/RoasterService/RoasterService.Roaster.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IRoaster"
contract="RoasterService.IRoaster" name="WSHttpBinding_IRoaster">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
Is there if i comment all the wcf call then for dummy values application works fine. please suggest the appropriate solution
You're probably not disposing the WCF client instance at the end of the request. Look at this post for the gotcha's in working with WCF clients.

Getting Error : The size necessary to buffer the XML content exceeded the buffer quota

I have developed one console application and from there i have called WCF function after adding as web reference. my console application's web.config as per below..
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IApicaAzureMonitorAgentReceiverWCF"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://apicaWCF.cloudapp.net/ApicaAzureMonitorAgentReceiverWCF.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IApicaAzureMonitorAgentReceiverWCF"
contract="Dashboard2WCFData.IApicaAzureMonitorAgentReceiverWCF"
name="BasicHttpBinding_IApicaAzureMonitorAgentReceiverWCF" />
</client>
I am getting error : The size necessary to buffer the XML content exceeded the buffer quota. I have also tried it and increased maxbuffersize and etc. still could not resolved this. hope anyone can here help me to sort out this issue.
Thanks.
Arun
Finally i got solution , the problem was with stored procedure parameter data type and got this solution using attaching process mechanism in visual studio, so i have debug the wcf function from console application and got exact error in WCF catch block.

How do I configure a WCF service that calls other services behind a load balancer?

I haven't deployed behind a load balancer before. My customer has a WCF service built and tested on servers using a service model configuration that is relatively straightforward. It provides a service to return an image of a map for another application. To get the map, it calls other services.
The service was built in Visual Studio 2010 targeting the 3.5 framework. The customer is using IIS 7.5 and an F5 load balancer. When moving to the production server, the Web.config was changed to add the load balancer behavior and specify the endpoint to show the physical and logical address of the service:
<services>
<service behaviorConfiguration="Service.Service1Behavior" name="StaticMapImageService.Data.MapImageService">
<endpoint
address="https://gis.customer.com/StaticMapImage/Service/StaticMapImageService.svc"
binding="basicHttpBinding"
bindingNamespace="http://customer.com"
contract="StaticMapImageService.Data.IMapImageService"
listenUri="http://hq-gis01.customer.net/StaticMapImage/Service/StaticMapImageService.svc"
behaviorConfiguration="SSLLoadBalancerBehavior">
</endpoint>
<endpoint
address="mex"
binding="mexHttpBinding"
bindingNamespace="http://werner.com"
contract="IMetadataExchange"/>
</service>
</services>
There is no entry for this service in the system.servicemodel/bindings section. The other services are configured in the bindings and client sections:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IAddressVerificationService"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard" maxBufferSize="999999999"
maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="999999999" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<binding name="BasicHttpBinding_IGeocoderService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="999999999" maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="999999999" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<binding name="PCMilerSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="999999999" maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="999999999" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="WSHttpBinding_IGeocoderService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="999999999"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://gis.customer.com/AddressVerification/Service/AddressVerificationService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAddressVerificationService"
contract="AddressVerificationService.IAddressVerificationService"
name="BasicHttpBinding_IAddressVerificationService" />
<endpoint address="https://gis.customer.com/Geocoder/Service/GeocoderService.svc/ws"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IGeocoderService"
contract="GeocoderService.IGeocoderService" name="WSHttpBinding_IGeocoderService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="https://gis.customer.com/Geocoder/Service/GeocoderService.svc/soap"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGeocoderService"
contract="GeocoderService.IGeocoderService" name="BasicHttpBinding_IGeocoderService" />
<endpoint address="http://hq-miler02.customer.net/MultiMiler/ALKWS/PCMiler.asmx"
binding="basicHttpBinding" bindingConfiguration="PCMilerSoap"
contract="PCMiler.PCMilerSoap" name="PCMilerSoap" />
</client>
There was a problem when the service was deployed to a server behind the load balancer. When I try to call the service from WCFStorm or WebServiceStudio I get the message "The provided URI scheme 'https' is invalid; expected 'http'.
The endpoints for the service itself look right to me. However in the development and testing versions of the config, the client section uses http instead of http, while on the production servers it uses the load balancer's https address.
This seems like it should be obvious, but we're missing it. Can anybody give us a clue?
We have wcf services set up behind Windows Network Load Balancing without any issue (well there was one, but it wasn't to do with NLB).
I think it's to do with the address. The web server is usually unaware that it's behind a load balancer. all it sees are requests coming from one source, the load balancer. Your binding has it listening for https, but unless the load balancer talks to the web server over https, which is rare, the requests are coming over http, hence the error.
You need to either change the address to http, or set the load balancer to talk to the web server via http.
So I'm late to the party, but i ran into the same issue with calling a service behind F5. Change your client binding security to Transport instead of None.

Resources