WCF IIS-hosted wsHttpBinding service - svcutil generates proxy with basicHttpBinding! - wcf

I consider myself pretty expert at WCF but this has me stumped. I don't know if this is a .NET Framework 4/WCF 4 thing with it's automatic configuration or what but I am getting strange behavior. I basically have a WCF 4 WCF service hosted in IIS project. It all worked and then I went in and switched the config from basicHttpBinding to wsHttpBinding. I tried to Update the Service Reference in my consuming app and I get basicHttpBinding output in the generated config. So, of course, I dropped down and ran svcutil.exe aggainst the .svc file and same results. This is the config file (Blah substituted for name that I can't use in public):
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Windows"></authentication>
<identity impersonate="true"/>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpEndpointBinding">
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="Blah.Services.RONScheduler.BlahService.BlahDataServiceBehavior"
name="Blah.Services.RONScheduler.FAMService">
<endpoint address="BlahDataService" binding="wsHttpBinding" bindingConfiguration="WSHttpEndpointBinding"
name="WSHttpEndpoint" contract="Blah.Services.RONScheduler.FAMService.IBlahDataService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Blah.Services.RONScheduler.BlahService.BlahDataServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
This is what I get generated out before I clean out the unncessary stuff:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IBlahDataService" 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/BlahService/BlahDataService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IBlahDataService"
contract="IBlahDataService" name="BasicHttpBinding_IBlahDataService" />
</client>
</system.serviceModel>
As you can see it's as if it's ignoring the wsHttpBinding setting in the config. What gives?

Have you checked your default protocol bindings, a new feature in WCF 4 ??
By default, they're in your machine.config, and should look like this:
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" bindingConfiguration="" />
<add scheme="net.tcp" binding="netTcpBinding" bindingConfiguration=""/>
<add scheme="net.pipe" binding="netNamedPipeBinding" bindingConfiguration=""/>
<add scheme="net.msmq" binding="netMsmqBinding" bindingConfiguration=""/>
</protocolMapping>
So this kinda implies to me that if you're hitting a HTTP address, WCF 4 will use basicHttpBinding by default.
You can change those bindings in your own configs, if needed.
Found this in A Developer's Introduction to Windows Communication Foundation 4

Given the configurations you provided, my guess would be that the service name is invalid and the host falls back to default configuration.
Make sure the service name matches the implementation class name.
I came to this conclusion because the interface name is Blah.Services.RONScheduler.FAMService.IBlahDataService and the class name is Blah.Services.RONScheduler.FAMService. It looks like there is something missing after FAMService.

Related

WCF Streaming not able to transfer large files

I am making a WCF Service for transfering files. I have only basic WCF understanding and followed the MSDN tutorial: WCF Tutorial
I started using byte arrays for transfering the files but as soon as the files got a little big (100kb was enough) it would fail with bad request.
I followed another guide and changed to streaming with messages, and it works with small files as well but fails with bigger ones like the old version. I suspect the fault lies in my config file as the one generated by svcutil.exe doesn't say anything about streaming.
This is my clients app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IDocPublisher" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="200000000" maxStringContentLength="200000000" maxArrayLength="200000000"
maxBytesPerRead="200000000" maxNameTableCharCount="200000000" />
<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://localhost:8000/ServiceModelSamples/docPublisherWebService/docPublisher"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDocPublisher"
contract="IDocPublisher" name="WSHttpBinding_IDocPublisher">
<identity>
<userPrincipalName value="Emil-PC\Emil" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
And this is the servers app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"
httpHelpPageEnabled="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior"
name="DocPublisher">
<endpoint address="http://localhost:8000/ServiceModelSamples/docPublisherWebService"
name="basicHttpStream"
binding="basicHttpBinding"
bindingConfiguration="httpLargeMessageStream"
contract="IDocPublisher" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="httpLargeMessageStream"
maxReceivedMessageSize="200000000"
maxBufferSize="200000000"
transferMode="Streamed"
messageEncoding="Mtom" />
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
Try to increase send timeout and reader quotas on client side, set buffer size on server side.
Turns out the config files weren't the real problem, the problem was that the servers app.config was never used as the msdn tutorial doesn't use app.config but creates the endpoints in the main method.

WCF - Conflicting endpoints after .Net 4.5 installation

I'm recently installed the 4.5 framework on our development web server which runs IIS 7.5 on Windows Server 2008. After installation, two web services started having the same error. These web services were built using the MS REST Starter Kit. Here is the error I'm getting.
A binding instance has already been associated to listen URI . If two endpoints want to share the same ListenUri, they must also share the same binding object instance. The two conflicting endpoints were either specified in AddServiceEndpoint() calls, in a config file, or a combination of AddServiceEndpoint() and config.
Here is a copy of the system.service model section of our config file.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<webHttpBinding>
<binding>
<security mode="Transport" />
</binding>
</webHttpBinding>
<wsHttpBinding>
<binding name="EnterpriseIdentityBinding" 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="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://betaapps/EnterpriseIdentity/V1/UserService.svc"
binding="wsHttpBinding" bindingConfiguration="EnterpriseIdentityBinding"
contract="UserServiceWCF.IUserService" name="wsSecureUsers" />
<endpoint address="https://betaapps/EnterpriseIdentity/V1/RoleService.svc"
binding="wsHttpBinding" bindingConfiguration="EnterpriseIdentityBinding"
contract="RoleServiceWCF.IRoleService" name="wsSecureRoles" />
</client>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization principalPermissionMode="Custom">
<authorizationPolicies>
<add policyType="Hsmv.Web.Security.IdentityModel.HttpContextWithRolesPolicy, Hsmv.Web.Security" />
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Any idea why this error would occur after installing .Net 4.5?
I would like to add that I tried removing this section and it does work without it.
<webHttpBinding>
<binding>
<security mode="Transport" />
</binding>
</webHttpBinding>
I use this because this service runs on ssl. I heard that WCF 4.5 tries to create bindings and endpoints for you so they don't need to be in the web.config. So I wondered if this section is being automatically built by WCF and is not needed. Or is my thinking incorrect?
Thanks!
I am from WCF team. Thanks for reporting this issue. WCF team will continue to investigate this issue for fix. While we investigate you can work around this by explicitly configuring a webHttp endpoint in your configuration file. Service will be the same by behavior like before. Try to follow these simple steps.
(I am taking the configuration file that you have published in this post as a starting point)
Comment out the <standardEndpoints> tag in your configuration file:
<!--<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>-->
Add this end point behavior to your list like this:
<behaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
Explicitly configure your service endpoint in the config file like this. For highlighted attribute values substitute your service type name and contract name respectively (Note: if you don’t have a contract defined for service, then insert service type name in contract=”” too)
<services>
<service name="WcfRestService1.Service1">
<endpoint address="" binding="webHttpBinding" contract="WcfRestService1.Service1" behaviorConfiguration="REST" />
</service>
</services>
In my case, the problem solved once I removed the <security/> tag from the web.config. I had it setted to "none", so this may not apply to your particular case.

wcf exception: The server did not provide a meaningful reply

I have a service that use the tcp binding and this services allows to the clients interact with the database. I use EF and self tracking entities.
One thing that I want to do is store files in the database, so to not overload the wire, i have two tables with their corresponding entities. One table Documents with the information of the documents (type, size... etc) and other table, Files, that store the binary information, the file.
Well, in local, when I run the client and the service in the same computer, I can store the files that I want. I try with a file of 6MB. But If I run the client in other computer in the same lan, then I have many problems.
For example, if I try to store a small file, 50kB, I don't have problems, but if I try to store the file of 6MB, then I can get different errors.
For example, if I configure in the client a low timeout, for example 1 minute, I get the error:
System.TimeoutException: This request operation sent to net.tcp://192.168.1.5:7997/CMMSHost did not receive a reply within the configured timeout (00:01:00).
If I configure the client to have a timeout of 10 minutes, then I get the following error:
The server did not provide a meaningful reply
The service is hosted in a wpf application, and in the Begin method of the serve that add the document in the database, I send a text with a log to know if the call is received or not. When I get some of the errors, the call in not received, so I think that the problem perhaps is that the self tacking entity for some reason does not arrive to the service.
My app.config for the service is the following:
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="tcpBinding"
name="NetTcpBindingEndpoint"
contract="GTS.CMMS.Service.IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint contract="IMetadataExchange" binding="mexTcpBinding" address="net.tcp://localhost:5000/mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behaviorConfig">
<!--
<serviceMetadata httpGetEnabled="true" />-->
<!--Necesario para poder enviar excepciones desde el servicio al cliente.-->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100" />
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding" maxBufferSize="67108864"
maxReceivedMessageSize="67108864" maxBufferPoolSize="67108864"
transferMode="Buffered" closeTimeout="00:00:10"
openTimeout="00:00:10" receiveTimeout="00:20:00"
sendTimeout="00:01:00" maxConnections="100">
<security mode="None"/>
<readerQuotas maxArrayLength="67108864" maxBytesPerRead="67108864" maxStringContentLength="67108864"/>
<reliableSession enabled="true" inactivityTimeout="00:20:00" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
And the client configuration is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:01: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:20:00"
enabled="true" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://192.168.1.5:7997/CMMSHost" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService" contract="IService"
name="NetTcpBinding_IService" />
</client>
</system.serviceModel>
</configuration>
I use a large readquotes, to try to discard that the problem is the size of the file, but the problem persists.
Thanks.
I don't think this is an issue related to WCF. I assume its rather related to your IIS.
Can you try the following code snippet in your web.config?
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="524288000"/>
</requestFiltering>
</security>
</system.webServer>

SOAP Security Negotiation Error in WCF Duplex service

I'm working on a WCF service with duplex communications and having an issue getting it to work anywhere other than through localhost on my dev machine.
No matter what I do, it comes up with the following error:
{"Security Support Provider Interface (SSPI) authentication failed.
The server may not be running in an account with identity
'host/crpnyciis20e'. If the server is running in a service account
(Network Service for example), specify the account's
ServicePrincipalName as the identity in the EndpointAddress for the
server. If the server is running in a user account, specify the
account's UserPrincipalName as the identity in the EndpointAddress for
the server."}
My service Web.config is as follows:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="wsDualHttpBinding"/>
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
And my client's App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IMessagingService" 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">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00" />
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint
binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IMessagingService"
contract="CTMessagingServiceReference.IMessagingService" name="WSDualHttpBinding_IMessagingService">
<identity>
<userPrincipalName value="nbdfp2k" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Any ideas what I could do to get around this issue? If there is any other code that would be helpful in diagnosing, just let me know... none of the rest of it really has to do with connection config, that I know of.
Not sure if this would fix your issue, but you are missing the address in the client endpoint and also the clientbaseaddress in your binding configuration(It should differ from your endpoint address).
Not sure if this is the ideal way of doing it but you can try removing the following "identity" node from your client config -
<identity>
<userPrincipalName value="nbdfp2k" />
</identity>

Calling a WCF service from another WCF service

I have a WCF service hosted on a windows service on my Server1. It also has IIS on this machine. I call the service from a web app and it works fine. But within this service, I have to call another WCF sevice (also hosted on a windows service) located on Server2. The security credentials are set to "Message" and "Username". I have an error like "SOAP protcol negociation failed". It's a problem with my server certificate public key that doesn't seem to be recognise. However, if I call the service on the Server2 from Server1 in a console app, it works fine.
I followed this tutorial to set up my certificates : http://www.codeproject.com/KB/WCF/wcf_certificates.aspx
Here's the config file from my service on Server1 that tries to call the second one :
<endpoint address=""
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ITraitement" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<client>
<endpoint address="http://Server2:8000/servicemodelsamples/service"
behaviorConfiguration="myClientBehavior" binding="wsHttpBinding"
bindingConfiguration="MybindingCon" contract="Microsoft.ServiceModel.Samples.ICalculator"
name="">
<identity>
<dns value="ODWCertificatServeur" />
</identity>
</endpoint>
</client>
<bindings>
<wsHttpBinding>
<binding name="MybindingCon">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceTraitementBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="myClientBehavior">
<clientCredentials>
<clientCertificate findValue="MachineServiceTraitement" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
And here's the config file from the web app that calls the service on Server1 :
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ITraitement" 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="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8020/ServiceTraitementPC"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITraitement"
contract="ITraitement" name="WSHttpBinding_ITraitement">
</endpoint>
</client>
Any idea why it works if if I call it in a console app and not from my service ? Maybe it has something to do with the certificateValidationMode="ChainTrust" ?
Well, finally it was just a matter of trusting the issuer of the certificate on the client machine. It was mentioned in the tutorial and I must have missed that step. Still wonder why it worked when calling from a console app, but... anyway, it works fine now.
Thanks !
When you call the service from the console app you are in the security context of the logged in user.
When you call the service from a service running in IIS, with default settings, you are in the security context of a local account NETWORK SERVICE.
The way to fix it is probably to set impersonate=true in the system.web section of your web.config.