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

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.

Related

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.

Just another "An existing connection was forcibly closed by the remote host" issue

I'm trying to access a WCF service on a company network. I'm using the proxy and config file generated by svcutil. The code looks like this:
using (Client client = new Client())
{
client.Open();
client.DoStuff();
}
Client is the client class in the generated proxy code, meaning it's derived from System.ServiceModel.ClientBase and implements the Contract interface.
And the config file looks like this:
<configuration>
<system.serviceModel>
<client>
<endpoint address="net.tcp://Address"
binding="netTcpBinding"
bindingConfiguration="Config"
contract="Namespace.Contract"
name="name">
<identity>
<servicePrincipalName value="Host" />
</identity>
</endpoint>
</client>
<bindings>
<netTcpBinding>
<binding name="Config"
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" />
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
I get the exception "An existing connection was forcibly closed by the remote host" every time the code reaches client.Open(). What really bothers is that when I try it from another computer, there's no exception. And on top of that, the config file used to have Transport security which was changed to None, and the computer where it works still has the old config file with
<security mode="Transport">
<transport clientCredentialType="Windows"
protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
whereas on the first machine and the server it's
<security mode="None">
<transport clientCredentialType="None" />
</security>
What can cause this? I've read numerous other questions here regarding this exception, but none seemed to resemble my issue.
SOLVED! I have set the security options in the wrong place.
The service was self hosted with ServiceHost, and the Security property wasn't set, so it defaulted to something else than None.
Check your Security settings for this project on your IIS (you are using IIS right?). I think it still says authentication type Windows.

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).

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 can't connect to an ASMX Web Service

I'm using WCF to connect to a remote web service (asmx) for testing at this point. The remote web service is unsecured for now (no https, no user name, password). I can add the WCF service reference, and all the classes are generated ok. When I make the call to the webservice, it just hangs.
So I can connect with the SOAP UI tool and return data just fine. I'm thinking it is something wrong with my binding. Anyone see anything I'm missing?
<system.serviceModel>
<bindings>
<!-- Need to change some settings here for HTTPS and Basic Auth when those go online-->
<basicHttpBinding>
<binding name="ServiceSoap" 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://<snip>/Service.asmx"
binding="basicHttpBinding" bindingConfiguration="ServiceSoap"
contract="PRIOrderService.ServiceSoap" name="ServiceSoap" />
</client>
</system.serviceModel>
Requesting the wsdl endpoint does not trigger a creation of the instance of your service. If you are using a custom service host factory look at that, otherwise look at the constructor of your service implementation or debug the service method itself.