WCF Service Binding taking default values instead of custom values - wcf

I have build an APi which is a WCF Service. In the web.config for the service i have specified a custom bindong looking like this:
<bindings>
<wsHttpBinding>
<binding name="FxBinding"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
closeTimeout="00:20:00"
openTimeout="00:20:00"
receiveTimeout="00:20:00"
sendTimeout="00:20:00"
messageEncoding="Mtom">
<readerQuotas
maxDepth="64"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<security mode="None"></security>
</binding>
</wsHttpBinding>
</bindings>
Telling the configuration to use the binding i have specified by setting the "name" attribute in the endpoint tag:
<services>
<service name="Dba.Admanager.Api.ListingServiceContract" behaviorConfiguration="Dba.Admanager.Api.ListingServiceContractBehavior">
<endpoint address="" binding="wsHttpBinding" name="FxBinding" contract="Dba.Admanager.ApplicationController.Api.IListingServiceContract">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
See. When i create an web reference to the service in VS2008 a app.config are generated.
In this app.config the binding used, should be the one specified above. But in the app.config is a default binding with default values in the "maxArrayLength" for instance.
<bindings>
<wsHttpBinding>
<binding name="FxBinding" 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="65536"
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="">
<extendedProtectionPolicy policyEnforcement="Never" />
</transport>
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://l-aar-00424012.corp.ebay.com/Admanager.Api/ListingServiceContract.svc"
binding="wsHttpBinding" bindingConfiguration="FxBinding" contract="WCFListingServiceContract.IListingServiceContract"
name="FxBinding">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
I can see that the client is using the FxBinding configuration, but why on earth all the values are default, i dont understand. Can anubody give at at clue on how to customize the binding-values and make it reflect on the "client"-part?
If i change the values manualle in the app.config i get the desired effect, but every time the webreference is updated, VS just adds a new binding with the default values.

Information such as maxArrayLength is not part of the WSDL, so the client cannot infer it and just takes default values.

As Darin already mentioned - since those binding parameters aren't part of the interoperable metadata between service and client, they can't be automagically picked up by the client when you create a new client proxy.
What you could do is this:
define your binding configurations in a separate config file and reference that on the server - i.e. put everything inside <bindings> into bindings.config and then reference it from your server side web.config or app.config:
<system.serviceModel>
<bindings configSource="bindings.config" />
</system.serviceModel>
Then copy that bindings.config to your client side and do the same thing there in your app.config.
Note: yes, Visual Studio will complain about the "configSource" not being defined and all - but that's just a flaw in the VS intellisense for config files. Trust me - it works - I use it everyday in production systems! Every configuration section in .NET has a "configSource" attribute!
With this method, you create one file that contains those binding configurations for your system and you can use it on both the server and the client side.

Related

Changing protocol from net.tcp to http, Wcf, gives me the error "No corresponding start element is open"

I am required to update the endpoints from net.tcp to http and all of them work fine except for one.
Configuration on the client web config side is as follow.
<endpoint address="http://myseriesservices/Quote.svc" behaviorConfiguration="DynamicTransportBehavior" binding="wsHttpBinding" bindingConfiguration="httpConfiguration" contract="EbqQuoteServiceReference.IQuote" name="Quote" />
<!--<endpoint address="net.tcp://myseriesservices/Quote.svc" behaviorConfiguration="DynamicTransportBehavior" binding="netTcpBinding" bindingConfiguration="Quote" contract="EbqQuoteServiceReference.IQuote" name="Quote" />-->
and wsHttpBinding
<wsHttpBinding>
<binding name="httpConfiguration" maxReceivedMessageSize="10485760" openTimeout="00:01:00" receiveTimeout="00:05:00" sendTimeout="00:05:00">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
and this is the configuration on the server side.
<service behaviorConfiguration="MexBehavior" name="OM.Mec.BF.Ebq.Quote">
<endpoint address="" bindingConfiguration="BasicHttpBinding_Large" name="BasicHttpBinding_Large" binding="wsHttpBinding" contract="OM.Mec.SC.Ebq.IQuote" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<!--<endpoint address="" bindingConfiguration="NetTcp_StreamingResponse" name="Quote" binding="netTcpBinding" contract="OM.Mec.SC.Ebq.IQuote" />
<endpoint address="Mex" binding="mexTcpBinding" bindingConfiguration="" name="QuoteService.MexBinding" contract="IMetadataExchange" />-->
<host>
<baseAddresses>
<add baseAddress="http://myseriesservices/Quote.svc" />
<!--<add baseAddress="net.tcp://myseriesservices/Quote.svc" />-->
</baseAddresses>
</host>
</service>
and BasicHttpBinding_Large
<binding name="BasicHttpBinding_Large" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
What could the reason be for getting this error?
I debugged on the backend and a call is made to the DB successfully but at the point of returning the data to the client it fails. net.tcp if fine, it only fails with http
There can be one of these reasons for this error
I think your call is failing due to the size of the object which you return from your service.
A second reason could be the serialization settings of your service as Net TCP (BinarySerializer) and HTTP (DatacontractSerializer) bindings use different serialization by default.
Solution for big size response would break your response in chunks and send it over HTTP. You can refer this link https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/chunking-channel
Which way did you use to host the service? If IIS is, we should not add the base address in the configuration since we should add the base address in the IIS site binding module.
Besides, it seems that the binding configuration is not coherent between the server and the client.
I suggest you call the service on the client side by using Adding service reference to generate the client proxy class, like below.
It could maintain the consistency of the binding configuration between the client and the server.
Feel free to let me know if the problem still exist.

WCF Service with security mode none

My WCF service works fine with Security Mode="Transport" and clientCredentialType="Windows" (with client and service on either one machine or two). But I need to put the service on the other side of a firewall where Windows Authentication is not possible. I know I can either install X.509 certs or use security="None" (to which I would add my own security protocol). But I cannot get "None" to work! I keep getting 'The socket connection was aborted' error.
Here is the config, please let me know if you spot anything. I have tried it without the 2 lines that specify clientCredentialType="none" but it makes no diff. P.S. Each time I make a config change I stop and restart both the client and the service.
SERVER CONFIG
<system.serviceModel>
<services>
<service name="OuterService.OutCardTrx">
<endpoint address="" binding="netTcpBinding" contract="OuterService.IOutCardTrx">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://jimt4.campus.internal:8081/PCIOutService"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="netTcpBinding">
<security mode="None" >
<transport clientCredentialType="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
CLIENT CONFIG:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IOutCardTrx" 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="None">
<transport clientCredentialType="None" />
<message clientCredentialType="None" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://jimt4.campus.internal:8081/" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IOutCardTrx" contract="OCS.IOutCardTrx"
name="NetTcpBinding_IOutCardTrx">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Not 100% sure this is the reason, but your binding security settings don't match between the client and the service.
Note that the default security for NetTcpBinding is Transport (for mode). You define None in your binding in the service config, but that binding is never assigned to the service endpoint, so your service is using the default settings for NetTcp.
On the other hand, you are setting the binding configuration on your client.
Try setting the binding configuration in your service endpoint like this:
<endpoint address="" binding="netTcpBinding"
bindingConfiguration="netTcpBinding"
contract="OuterService.IOutCardTrx">
This will assign your specified binding to the endpoint, with security set to "None". I would also recommend changing the binding configuration name to something other than "netTcpBinding" to avoid any possible confusion.
Did you try increasing the values for MaxItemsInObjectGraph, MaxReceivedMessageSize, MaxBufferPoolSize, MaxBufferSize, MaxArrayLength in both client/server configs? The default values are pretty low, try maxing them out to 2147483647.
Also try enabling tracing on the service to see further error details.

Accessing wcf web service with powershell2

I'm trying to write a cmdlet that accesses one of my wcf webservices.
I've been looking at the new cmdlet : New-WebServiceProxy, but it only really seems capable of consuming ASMX webservices.
I've seen this article; which is focussed around Powershell v1.0
I'd rather use a better method (if one exists).
http://keithhill.spaces.live.com/blog/cns!5A8D2641E0963A97!645.entry
From my other .net apps that consume this webservice, here's the sort of configuration i use;
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IMyService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="819200" maxArrayLength="1638400" maxBytesPerRead="409600" maxNameTableCharCount="1638400" />
<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="http://myServer/MyService/MyService.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMyService" contract="MyService.IMyService" name="WSHttpBinding_IMyService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Anyone wanna advise me?
Ultimately you are going to want to create a client side proxy object, compile that into a .NET assembly, create that proxy and program against it in PowerShell. New-WebServiceProxy was written to allow you to do that. I'm surprised that it would only work against ASMX services? Perhaps it isn't working for you because you don't have a MEX endpoint defined in your config file? See this article on how to create a MEX endpoint that will enable proxy generation for your web service.

WCF Multiple Service Configuration Issue

Scenario
Ignoring that fact that some of the settings might be wrong and inconsistent or just not there!.
Why does the program fail to compile when I try and put these 2 separate configurations for WCF Services into the same APP.CONFIG file? One was writen by myself and another by a friend, yet I cannot get the application to compile. What have I missed?
ERROR
Type Initialization Exception
CODE
<configuration>
<system.serviceModel>
<!--START Service 1 CONFIGURATION-->
<bindings>
<netTcpBinding>
<binding name="tcpServiceEndPoint" 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:05:00"
enabled="true" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address=""
binding="netTcpBinding" bindingConfiguration="tcpServiceEndPoint"
contract="ListenerService.IListenerService"
name="tcpServiceEndPoint" />
</client>
<!--END Service 1 CONFIGURATION-->
<!--START Service 2 CONFIGURATION-->
<services>
<service name="UploadObjects.ResponseService">
<!-- Define NetMsmqEndpoint -->
<endpoint address=""
binding="netTcpBinding"
contract="UploadObjects.IResponseService"
bindingConfiguration="TransactedBinding"/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="TransactedBinding">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<!--END Service 2 CONFIGURATION-->
</system.serviceModel>
</configuration>
A couple of observations:
Your <client> endpoint has no address:
<client>
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="tcpServiceEndPoint"
contract="ListenerService.IListenerService"
name="tcpServiceEndPoint" />
How do you expect your client code to know where to connect to?? You need to specify a full WCF service address in any client <endpoint>
Your <service> endpoint also is lacking an address - you either need to specify a full address here, or than you have to have a base address defined in your service! One of the two must be present:
<services>
<service name="UploadObjects.ResponseService">
<endpoint address="net.tcp://YourServer:5455/YourServiceAddress"
binding="netTcpBinding"
contract="UploadObjects.IResponseService"
bindingConfiguration="TransactedBinding"/>
</service>
or:
<services>
<service name="UploadObjects.ResponseService">
<endpoint address=""
binding="netTcpBinding"
contract="UploadObjects.IResponseService"
bindingConfiguration="TransactedBinding"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://YourServer:5455/YourServiceAddress" />
</baseAddresses>
</host>
</service>
Also, from your question, it's not clear what you're trying to do when you get the error:
are you trying to start up a service host that hosts the service? A console app, or IIS?
are you trying to connect a client side to a running service?

WCF Service Name & Binding Name

Scenario
I have two WCF Services combined in a single App.Config file.
I can't get the thing to run (the application compiles but fails at initialization of the services).
Question
I'm wondering whether I need to set the service name to be the same as something else that is also defined as part of the service overall?
ERROR
TypeInitializationException
{"Service 'MurexUploadObjects.ResponseService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element."}
CODE
<system.serviceModel>
<configuration>
<behaviors>
<serviceBehaviors>
<behavior name="Service1Bevhavior">
</behavior>
<behavior name="Service2Bevhavior">
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBloombergServiceEndPoint" 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:05:00"
enabled="true" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
<binding name="TransactedBinding">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<!--SERVICE ONE-->
<service name="INSERT NAME HERE">
<endpoint address="net.tcp://AP434190:8732/BloombergService/"
binding="netTcpBinding"
contract="BloomberPriceListenerService.IBloombergPriceListenerService"
bindingConfiguration="tcpBloombergServiceEndPoint"
name="tcpBloombergServiceEndPoint" />
</service>
<!--SERVICE TWO-->
<service name="INSERT NAME HERE">
<endpoint address="net.tcp://localhost:8735/private/MurexUploadObjects/ResponseService"
binding="netTcpBinding"
contract="MurexUploadObjects.IResponseService"
bindingConfiguration="TransactedBinding"
name="TransactedBinding"/>
</service>
</services>
</system.serviceModel>
</configuration>
The service name must be the fully qualified name of your service class, including the namespace, e.g.
<service name="YourServiceNamespace.YourService">
It can't be just anything - the name of the service class is used by ServiceHost to find the right service configuration.