WCF Client consuming multiple services - wcf

I'm trying to figure out how to set up my web.config (the client) to consume two different WCF web services one using the other using
I have the two endpoint, I guess I need two different Binding configurations. This is my current binding node:
<basicHttpBinding>
<binding name="WebServiceProxyServiceSoapBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
I can't add another basicHttpBinding node. The thing is if ALL I changed was the mode parameter in <security mode="Transport"> then the binding will work great for one or the other endpoint.
This seems like a common issue, but have not found an answer. Overall I'm not very experiences with WCF (if that is not obvious) outside the simple consume and call. Any help would be GREAT!
This article was close but not quite the same issue as they did not need a different security mode.:
How to consume multiple WCF services from one client
Thanks in advance.

You just need to add another <binding> node, with a different name and whatever different options you like, under the <basicHttpBinding> node.
Then, obviously, just make sure each client is configured to use the binding that's specific to them by setting the appropriate name in the bindingConfiguration attribute for each <endpoint> node.

I have the two endpoint, I guess I
need two different Binding
configurations. This is my current
binding node:
Not necessarily - if these two services use the same settings and same protocols, one binding configuration will do.
What you need to add two of is a client element:
<system.serviceModel>
<bindings>
..... (as you already have it) ....
</bindings>
<client>
<endpoint name="Service1Endpoint"
address="http://yourserver/service1.svc"
binding="basicHttpBinding"
bindingConfiguration="WebServiceProxyServiceSoapBinding"
contract="IWCFService1" />
<endpoint name="Service2Endpoint"
address="http://yourserver/service2.svc"
binding="basicHttpBinding"
bindingConfiguration="WebServiceProxyServiceSoapBinding"
contract="IWCFService2" />
</client>
</system.serviceModel>
That should do.
Of course, if your second service uses another binding, or needs different security settings, then yes, you'd need to add a second <binding name="something else" .....> under your <basicHttpBinding> node and reference that second binding configuration from one of your two client endpoints here.

Related

Calling WCF service from excel gives error on received message size

I am calling my WCF service from excel VBA code using moniker string. However, as my service returns large data as response, excel gives error message
"Maximum message size quota for incoming messages (65534) has been exceeded. To increase the quota used the MaxReceivedMessageSize property on the appropriate binding element"
Here is the moniker string:
addrToService = "service4:mexAddress=""net.tcp://localhost/MyApp/API/Excel/ExcelAPIService.svc/mexTCP"", "
addrToService = addrToService + "address=""net.tcp://localhost/PruCapWebCMHost/API/Excel/ExcelAPIService.svc"", "
addrToService = addrToService + "contract=""IExcelAPIService"", contractNamespace=""http://Prucap/Services"", "
addrToService = addrToService + "binding=""NetTcpBinding_IExcelAPIService"", bindingNamespace=""http://MyApp/Services"""
To resolve this, I increased the size in my WCF service's web.config file as shown below:
<netTcpBinding>
<binding name="NetTcpBinding_IPublicService" maxBufferPoolSize="8388608" maxBufferSize="8388608" maxReceivedMessageSize="8388608" portSharingEnabled="true">
</binding>
</netTcpBinding>
<basicHttpBinding>
<binding name="BasicHttpBidning_IPublicService" closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" receiveTimeout="00:05:00" maxReceivedMessageSize="8388608" />
<binding name="BasicHttpBidning_ISecureService" closeTimeout="00:05:00" openTimeout="00:05:00" sendTimeout="00:05:00" receiveTimeout="00:05:00" maxReceivedMessageSize="8388608" />
</basicHttpBinding>
....
<service name="ExcelAPIService" behaviorConfiguration="PublicServiceTypeBehaviors">
<endpoint address="" bindingNamespace="http://MyApp/Services" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IPublicService" contract="API.Service.ExcelAPI.IExcelAPIService" name="NetTcpBinding_IExcelAPIService" />
<endpoint address="" bindingNamespace="http://MyApp/Services" binding="basicHttpBinding" bindingConfiguration="BasicHttpBidning_IPublicService" contract="API.Service.ExcelAPI.IExcelAPIService" name="BasicHttpBidning_IExcelAPIService" />
<endpoint address="mex" bindingNamespace="http://MyApp/Services" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="mexTCP" bindingNamespace="http://MyApp/Services" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" />
</service>
According to various forums on this topic, the above solution should work. But this does not work in my case when called from excel. Is there anything I need to do from excel side to set the maxReceivedMessageSize? If yes then how can I do this using VBA code?
Additional information:
I use Office 2010 (with VBA), Windows 7 Prof, 64bit OS
The maximum size must be set by the client as well as the server. However, the service moniker form you are using does not support specifying this parameter.
From first hand experience I can tell you, using monikers may seem appealing at first, since it allows you to call services from VBA with minimal coding, but it is very limited in what it can do. I discovered, as no doubt you are in the process of dicovering as well, the best way to approach this is to build a proper WCF client - probably in .NET - and call the client class from your VBA, or even Excel directly.
If you are trying that and are still having trouble, please start a new thread so you can post your code, and more fully explain what you have tried, and what the problem is.
You should set maxReceivedMessageSize="2147483647" to increase message size.
Try increasing message size like:
<binding maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
--OR
<basicHttpBinding>
<binding name="BasicHttpBinding_IManagementService" 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="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="128" maxStringContentLength="2147483647"
maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
refer WCF Error "Maximum number of items that can be serialized or deserialized in an object graph is '65536'"
Wcf-The maximum message size quota for incoming messages (65536) has been exceeded?
UPDATE
You also can change endpoint/service behavior programatically.
Refer links:
How to: Specify a Service Binding in Code
How to: Programmatically Configure a WCF Endpoint
Update2:
Sorry Anil, Previously I totally overlook you are doing this in excel.
The easiest way for your scenario to use WCF service from VB6 is to create a .Net ComObject wrapper for the service client. Then in VB6 all your are doing is a create object and calling some methods on the object. All the WCF work takes place in the .Net com object.
Simply create the WCF client to the service in a separate project as described in this link. Register the .NET assembly as a type library which you would then link from the VB6 app : link.
Sources:
Using WCF in VB6
Integrating WCF Services with COM+
Communicate with WCF Windows Service in VB6?
Hope it helps. :)

WCF Service msg Size Error

I've two separated module (web based GUI and WCF based Server) and I'm using WCF service reference to access some methods from my GUI to Server. The problem occurs when GUI requests data from Server and it sends huge amount of data to GUI; Maximum Message Size error exception is thrown!
I increased the message size in appropriate section tag in Web.config file and it temporarily worked, but when the data- that is always growing in my case- reaches to the maximum allowed size the error happens again! I know that the bottle neck is on GUI side!
How can I solve the issue and is there any way to make the GUI service reference to handle ever-growing data?
Here is my GUI web.config file:
<pre>
</system.webServer>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IServerHelper" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="16777216" maxBufferPoolSize="524288" maxReceivedMessageSize="16777216" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" >
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 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://172.16.16.7:123456/ServerServices" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServerHelper" contract="ServiceReference1.IServerHelper" name="BasicHttpBinding_IServerHelper"/>
</client>
</system.serviceModel>
</pre>
thanks for helping me...
You can set these values up to int.MaxValue. If that's still not enough for your return message, you should try to split your messages. After all, that would be a message of 2GB. Maybe SOAP is not the best way to transport such a beast.

how do I use my web reference in MVC?

greeting folks, I need to reference an external service in my MVC app.
I'm using this service to validate an authentication token that one of our clients has requested we use.
I'm porting an older project to MVC.
I added a web reference.
The config was generated like so:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ExternalServicesSoap" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
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://myapps.test.com/ExternalServices/ExternalServices.asmx"
binding="basicHttpBinding" bindingConfiguration="ExternalServicesSoap"
contract="AssertionService.ExternalServicesSoap" name="ExternalServicesSoap" />
</client>
In the older ASP.NET world, I could do the following on the specific service I am referencing, using the Assertion object defined in the external service reference.
var service = new ExternalServices();
Assertion assertion = service.Validate(Id);
if(assertion.Valid){}
This doesn't seem to be the exact case in the MVC project.
I seem to be working with WCF.
I'm not sure if I'm approaching this properly in the MVC world.
All I have to work with is an ExternalServiesSoap interface or an ExternalServicesSoapChannel interface.
None of which return an Assertion object like in the ASP.Net world.
They both have the Validate method but return a ValidateAssertionResponse.
The response object doesn't have any useful properties; just a response body.
The Assertion class is still accessible but it doesn't seem to be returned by any of the interface methods.
Can anyone help me with how to properly use one of these interfaces?
thanks
Rather than adding a Service Reference, add a Web Reference. Right click on your project, select "Add Service Reference...". In the Add Service Reference dialog, click "Advanced", then click "Add Web Reference". This will generate a proxy that is appropriate for use with ASMX based services.

Calling SOAP UI mock service with WCF: "The provided URI scheme 'https' is invalid; expected 'http'."

A colleague of mine gave me a copy of a mock service project for SOAP UI. I can open and run this mock service fine on my machine.
It is running at address: http://localhost:8088/mockShipmentInformationService
The WSDL is provided on address: http://localhost:8088/mockShipmentInformationService_SOAPBinding?WSDL
Using the WSDL provided, I added a Service Reference to the application project. In order to test the methods calling the service, I also added the service reference to the Unit testing project.
For both projects, the following is added to the app.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="ShipmentInformationService_SOAPBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
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://localhost:8088/mockShipmentInformationService_SOAPBinding"
binding="basicHttpBinding" bindingConfiguration="ShipmentInformationService_SOAPBinding"
contract="ShipmentInformationService.ShipmentInformationService"
name="ShipmentInformationServicePort" />
</client>
</system.serviceModel>
As you can see, the URL is using the normal http protocol, not https. Also, my security mode is set to "none". Yet, I keep on getting the following error message, when attempting to call the service method:
The provided URI scheme 'https' is invalid; expected 'http'.
Parameter name: via
What gives? Might there be some URLs defined somewhere that are wreaking havoc? Where should I look?
I just discovered that it was all in the app.config files. The application project had a wrong URL in the applicationSettings section and the URL wasn't present there for the unit testing project. I can now at least call the service, although I am having some other issues now.

When does WCF NetTcpBinding need full trust on the client?

I'm using WCF to communicate to several servers.
For my local server netTcpBinding works like expected, no problems.
But when I try to connect to my remote server (Azure) using the following netTcpBinding in app.config, this will crash the application on initialization since the netTcpBinding can't be created without full trust.
This binding in the app.config file,
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="None" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
It will result in this error:
An error occurred creating the configuration section handler for "system.serviceModel/bindings": That assembly does not allow partially trusted callers. (K:\Somepath\Testing.exe.Config line 6)
The strange thing: In the app.config file I got client endpoints connecting to other netTcpBindings (without declaring them explizitely in the binding section).
Why do these generic netTcpBindings work in partial trust, but the one I showed above does not?
Or am I just confused by this error message and the problem is not about full trust?
Update: If I remove the <binding> section the stuff will run without problems. So I'm allowed to use netTcpBinding in partial trust, but I'm not allowed to modify the parameters? This is a pity since I'd like to have some form of encryption on my communication.
NetTcpBinding in general is not supported in partial trust environments.
While the basic communication works fine (as you've seen in other environments), features like TransportSecurity and ReliableMessaging (which you have on your sample configuration) are explicitly not supported on partial trust (it sucks, big time).