WCF metadata shows incorrect service URI on HTTPS - wcf

Using .NET 4.7.1 and minimal WCF configuration, the WSDL, when accessed from HTTPS, shows a HTTP address, and shows the incorrect host unless port 80 is enabled in the configuration.
This service should only be available on HTTPS, which will be enforced by a firewall rule further along.
My configuration looks like this
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="True"/>
<useRequestHeadersForMetadataAddress/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
And the result looks like this in a browser (demonstrating incorrect scheme and incorrect host. Sorry that I must block out most of this, but you should be able to get what I'm saying...)
resulting wsdl
I understand that "useRequestHeadersForMetadataAddress" tells WCF that I indeed want the WSDL right next to the service. I assumed it also should be able to handle the same intentions for scheme.
Any thoughts?

My issue was assuming I didn't need to specify binding configuration. Without binding configuration, I don't think WCF can figure out you want HTTPS bindings, and all problems flowed from there.
So, unfortunately, my web.config grows to twice its size!
<basicHttpBinding>
<binding name="SecureServiceBinding" closeTimeout="00:02:00" openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="20480000" maxBufferSize="10240000" maxReceivedMessageSize="10240000" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" messageEncoding="Text">
<readerQuotas maxDepth="100" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="2147483647"/>
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>

Related

Calling a webservice from a C# dll from within CLASSIC ASP

I'm a windows dev with very little knowledge of web applications and ASP. I'm trying to create a C# dll (which is making a webservice call) for someone, that is being called from a CLASSIC ASP app.
It all started from a WinForms test app that successfully loaded a WSDL and called that web service. Now the requirement is to take the test app functionality, move it to a dll and call that dll from the ASP app. I naively left the appconfig file there, and when that dll was called, he got this well known error:
Could not find default endpoint element that references contract Service1.MyService in the
ServiceModel client configuration section. This might be because no configuration file was found
for your application, or because no endpoint element matching this contract could be found in the
client element.
I understand that classic asp doesn't have config files - I read a lot of posts about it, and most of the relevant ones mention to use BasicHTTPBinding and provide an endpoint address on the fly. How do I do that? Any examples?
I saw this answer:
All I needed to do is to create a BasicHTTPBinding and provide an endpoint address on the fly.Then create a new instance of the web service using the created binding and endpoint address.
But i'm not sure how to do it.
This is the appconfig that worked for the winforms app:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyService">
<security mode="Transport">
<transport clientCredentialType="Certificate" proxyCredentialType="None"
realm="" />
</security>
</binding>
<binding name="BasicHttpBinding_ICustomerService" 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="https://MyService.svc"
behaviorConfiguration="custom" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IMyService" contract="MyService.IMyService"
name="BasicHttpBinding_IMyService" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="custom">
<customInspector />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="customInspector" type="CustomBehaviors.CustomBehaviorExtensionElement, CompeteDataServiceTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
You will need to configure the service through code, as there is no config file in this case. See Configuring WCF Services in Code.

Security Exception calling Reporting Services from a Windows Service

I am trying to call the web service for SQL Server Reporting Services from a Windows Service. I can successfully make the call from an Asp.Net MVC website, but when I try to use exactly the same code from a Windows service (with seemingly the same WCF configuration), I get the following error...
Inner Exception: System.ServiceModel.Security.MessageSecurityException
- The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM'.
Inner Exception: System.Net.WebException - The remote server returned
an error: (401) Unauthorized.
BOTH the application pool for my Asp.Net MVC site AND the Windows Service are set up to use the "Network Service" user.
Here is my WCF configuration in the config file...
<system.serviceModel>
<serviceHostingEnvironment
aspNetCompatibilityEnabled="true"/>
<bindings>
<basicHttpBinding>
<binding name="ReportExecutionServiceSoap" 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 maxArrayLength="2147483647"
maxStringContentLength="2147483647"
maxBytesPerRead="2147483647"
maxDepth="2147483647"
maxNameTableCharCount="2147483647"
/>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" proxyCredentialType="None" realm=""/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://myserver/ReportServer_MSSQL2008/ReportExecution2005.asmx"
binding="basicHttpBinding" bindingConfiguration="ReportExecutionServiceSoap"
contract="ReportService.ReportExecutionServiceSoap" name="ReportExecutionServiceSoap" behaviorConfiguration="ImpersonationBehaviour" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="ImpersonationBehaviour">
<clientCredentials>
<windows allowedImpersonationLevel="None" allowNtlm="true"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
I have tried all the different "allowedImpersonationLevel" and have tried it without this behaviour defined at all.
Make you have referenced all codes need to run the windows app at som point.

WCF Configuration for Endpoint in Another Project

I have two projects in a single solution. One project, let's call it MainProject, becomes an executable. The other project, let's call it ControlsProject, contains UserControl's and is referenced (and used) within the MainProject. The ControlsProject also has a WCF Service Reference.
I have a two questions regarding this configuration:
Can I just copy the WCF configuration from the ControlsProject to the MainProject (which I don't believe I can per " How to include Web reference endpoint configuration in another project ")
In the ControlsProject configuration, the contract doesn't have a fully qualified namespace but rather a name such as 'ServiceName.IServiceInterfaceName'. What should the contract name be since the ControlsProject output will be a file located in the bin folder of the MainProject?
I've tried just copying the configuration over, but received the exception: "Could not find default endpoint element that references contract 'MyService.IMyService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element." When I copied over the configuration, I fully qualified the name of the interface as ControlsProject.MyService.IMyService.
Any help you can provide is appreciated!
UPDATE (7/14/2011 5:28pm EST)
Here is the snippet from my client app.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IStatService" 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://intranet/StatService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IStatService"
contract="StatService.IStatService" name="BasicHttpBinding_IStatService" />
</client>
</system.serviceModel>
Here is the snippet from my web service web.config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Anytime you see the "Could not find default endpoint element for such and such contract" then your actual contract (the interface) is not referenced correctly in the app.config file. Go to the interface contract in the controls project double check the namespace it's in, you need that exact namespace."Interface name" as the contract element in the app.config. You also need to make sure your service name=Namespace.MyService is the correct namespace and class. One short way to know if you're right (this is only if you have resharper), in the appconfig where you declare service name= put the cursor over the service name and namespace and hit F12, if it doesn't take you anywhere you're referencing a namespace and class that don't exist, same goes for the contract=, if you F12 on that contract and it doesn't take you there, it's not referenced correctly (possibly misspelled).

WCF 3.0 Service Contract method will return 992 rows but not 993 rows. 50 column observable collection

When I try to run it with my test console application ... get error
An error occurred while receiving the HTTP response to --http://d3w9501.americas.hpqcorp.net/SimpleWCF/SimpleWCF.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.
when I try to run it from my silverlight application it pops up a login box.
Here is the serviceModel configuration in web.config
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="WSBigQuotaConfig" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2097152" maxBufferPoolSize="524288" maxReceivedMessageSize="2097152" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2097152" maxArrayLength="2097152" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
I see a whole bunch of limits in the readerQuotas,
2097152 / 990 = 2k per row and that doesn't seem a whole lot for 50 columns (40 char average).
So I think you just hit one of the limits.

WCF Client consuming multiple services

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.