WCF Single Service Implementation - Multiple Behaviours, Funny WSDL - wcf

I have a simple IIS hosted service that I need to expose both through a wsHttpBinding endpoint without throttling and a basicHttpBinding endpoint with throttling.
I configure my services as follows:
<service name="Calculator">
<endpoint address="http://localhost/WCFTwoEndpoints/Calculate.svc"
binding="wsHttpBinding" bindingConfiguration="" name="Calculator"
contract="WCFTwoEndpoints.ICalculate" />
</service>
<service name="ThrottledCalculator" behaviorConfiguration ="Throttled">
<endpoint address="http://localhost/WCFTwoEndpoints/ThrottledCalculate.svc"
binding="basicHttpBinding" bindingConfiguration="" name="ThrottledCalculator"
contract="WCFTwoEndpoints.ICalculate" />
</service>
This gives me two service endpoints, I can browse to each .svc individually and pull up the WSDL. Problem is, in each case the WSDL describes the service as using basicHttp binding, I would have expected wsHttp binding for the Calculate.svc.
I've pasted a section of the WSDL below:
<wsdl:binding name="BasicHttpBinding_ICalculate" type="tns:ICalculate">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Addition">
<soap:operation soapAction="http://tempuri.org/ICalculate/Addition" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Calculate">
<wsdl:port name="BasicHttpBinding_ICalculate" binding="tns:BasicHttpBinding_ICalculate">
<soap:address location="http://rb-t510/WCFTwoEndpoints/ThrottledCalculate.svc"/>
</wsdl:port>
</wsdl:service>
I think I've missed something obvious here but I can't spot it. Any ideas?
Many thanks
Rob.

Related

deploy WCF service with public IP

I created a WCF application that must be accessible on internet.
I deployed this application on a WS2008 R2 server with IIS. This server have a private IP but I configure NAT redirection on port 35000.
When I put the correct URI (with public IP) on a web browser, I can show the service page correctly but the link generated by IIS to show WSDL is not correct, I have the server name instead of public IP like this :
http://serverName:35000/ServiceName.svc?wsdl
instead of
http://publicIP:35000/ServiceName.svc?wsdl
so when I click on the link, the server name can't be resolve.
In my web.config file, I add an endpoint with the correct IP, and I also try to add an identity tag and DNS tag with the public IP but it doesn't work.
This is my web.config :
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="myNamespace.ServiceName.svc">
<endpoint address="http://xxx.xxx.xxx.xxx:35000/myNamespace/ServiceName/" binding="wsHttpBinding" contract="myNamespace.IServiceName">
<identity>
<dns value="xxx.xxx.xxx.xxx" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
This is the end of WSDL :
<wsdl:service name="ServiceName">
<wsdl:port name="BasicHttpBinding_IServiceName" binding="tns:BasicHttpBinding_IServiceName">
<soap:address location="http://serverName:35000/ServiceName.svc"/>
</wsdl:port>
</wsdl:service>
I also try in IIS to add the public IP as hostname but I obtain an error.
Thanks for your help
The solution is to add the mex endpoint :
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
and it works perfectly...

WCF BasicHttpBinding - Where can I find SOAP1.1 in WSDL

I've been trying to find out which version of SOAP 1.1/1.2 being using in WSDL generated using WCF BasicHTTPBinding. But I've not been able to pin-point.
I need to confirm this so that I can tell me clients that we are using specific version of SOAP. The requirement is to use SOAP 1.1. From what I read BasicHttpBinding uses SOAP1.1 but not being able to find or check.
Could someone please help.
e.g.
<wsdl:definitions name="MyService" targetNamespace="http://mydomain.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://spotless.com/isb/services" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
In your WSDL definition WCF includes namespaces for both SOAP 1.1. and SOAP 1.2. Namespace for SOAP 1.1 has prefix soap. SOAP 1.1 endpoint will use only this namespace:
<wsdl:binding name="SomeBinding" type="...">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="GetTime">
<soap:operation soapAction="..." style="..." />
<wsdl:input name="...">
<soap:body use="..." />
</wsdl:input>
<wsdl:output name="...">
<soap:body use="..." />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="...">
<wsdl:port name="..." binding="tns:SomeBinding">
<soap:address location="..." />
</wsdl:port>
</wsdl:port>
Do you see all these elements prefixed by soap? That means SOAP 1.1 because soap prefix is defined for SOAP 1.1 namespace. If it uses soap12 prefix instead it will mean SOAP 1.2.
If WCF service has multiple endpoints it will have multiple wsdl:port elements and each can refer to its ownwsdl:binding specification with different version of SOAP and different policies (I skipped policy references in the example).
BasicHttpBinding in WCF always uses SOAP 1.1.

WCF RoutingService not routing wsDualHttpBinding with callbacks

I´m having problems using the .Net 4.0 Routing Service connecting to a service using callbacks. To my understanding both binding and callbacks are supported by the Routing Service. Service and Client alone are operating fine.
What I did, was taking the MS WCF and WF Samples located here: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35ec8682-d5fd-4bc3-a51a-d8ad115a8792&displaylang=en
and changed the configuration to match the binding of my service. I can call operations via the routing service from the client to the service, only callbacks from service to the client are not received by the client.
The routing service is configured as follows, using a console application as a host
using (ServiceHost serviceHost =
new ServiceHost(typeof(RoutingService)))
{
serviceHost.Open();
Console.ReadLine();
}
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true" />
</diagnostics>
<services>
<!--ROUTING SERVICE -->
<service behaviorConfiguration="routingData" name="System.ServiceModel.Routing.RoutingService" >
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/routingservice/router"/>
</baseAddresses>
</host>
<endpoint address=""
binding="wsDualHttpBinding"
name="reqReplyEndpoint"
contract="System.ServiceModel.Routing.IRequestReplyRouter"
bindingConfiguration="UnSecureBinding"/>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="routingData">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true" />
<routing filterTableName="routingTable1" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsDualHttpBinding>
<binding name="UnSecureBinding">
<security mode="None" />
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint name="NotificationService"
address="http://localhost/CommServices/NotificationService.svc"
binding="wsDualHttpBinding"
bindingConfiguration="UnSecureBinding"
contract="*" />
</client>
<!--ROUTING SECTION -->
<routing>
<filters>
<filter name="MatchAllFilter1" filterType="MatchAll" />
</filters>
<filterTables>
<filterTable name="routingTable1">
<add filterName="MatchAllFilter1" endpointName="NotificationService" />
</filterTable>
</filterTables>
If I enabling ServiceModel tracing, I can see an ArgumentException deep in the WCF Stack, a trace I´havent followed so far.
Can anyone give a hint into the right direction, or correct me If my assumptions concerning the callback capabilities of the RoutingService are wrong.
TIA & Cheers
Dominik
In case someone stumbles like I did, the problem was the contract on the router endpoint. RequestReplyRouter does not support callbacks but IDuplexSessionRouter does.
<endpoint address=""
binding="wsDualHttpBinding"
name="reqReplyEndpoint"
contract="System.ServiceModel.Routing.IDuplexSessionRouter"
bindingConfiguration="UnSecureBinding"/>
Regards
Dominik

WCF Call not showing in Fiddler2

I have a simple WCF Service with basicHttp binding. The service is hosted locally (Win7 laptop) in IIS7. I'm able to browse the service at: http://localhost/musicstore/musicstore.svc
(port 80)
I've developed a simple windows form client app to call the service. It works fine but I'd really like to see the message call / response through Fiddler2. Fiddler2 will happily report traffic as I browse the web so I can't understand why it's not picking up this WCF call?
Is there another way to view the data on WCF calls. Maybe there's a Microsoft Tool?
The client config is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost/musicstore/musicstore.svc"
binding="basicHttpBinding" bindingConfiguration="" contract="MusicStore.IMusicStore"
name="BasicHttp" />
</client>
</system.serviceModel>
</configuration>
The service config is:
<services>
<service behaviorConfiguration="MusicStoreBehavior" name="MusicStore">
<endpoint address="" binding="basicHttpBinding" contract="IMusicStore">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
The easiest way to see what WCF is doing is to turn WCF's own logging on. You can do this by editing your web.config and adding
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\logs\messages.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="false"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="false"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000"/>
</diagnostics>
</system.serviceModel>
MSDN has more detailed information on what you can configure. You can view the logs in the Service Trace Viewer.
There are many duplicates of this question, many of which have correct answers. You should use http://localhost.fiddler/ as the target and .NET will properly proxy the request. Fiddler will then change "localhost.fiddler" to "localhost" before passing on the request.
You can modify your client's configfile:
<configuration>
<system.net>
<defaultProxy>
<proxy bypassonlocal="false" usesystemdefault="true" />
</defaultProxy>
</system.net>
</configuration>
Or you could use:
GlobalProxySelection.Select = new WebProxy("127.0.0.1", 8888);
From: Fiddler site
I had the same problem and fixed it this way:
Host your service in IIS express
Add a binding to your external LAN ip using applicationhost.config of IISExpress in Documents/IISExpress/config
Use the proxy configuration of dutch nico (see below)
Make sure your client application uses your 'external' ip. So 192.168.1.X instead of localhost.
You might have to change your WCF config to allow multiple bindings for asp.net 4.0
<serviceHostingEnvironment multiplesitebindingsenabled="true"/>

.net 4 WCF Endpoint in generated metadata (WSDL) points to node rather than virtual host hosted on load balanced (NLBS) IIS6

This is real simple. I have a wcf service (nothing fancy, just New Project-> WCF Service Application), that runs great in Visual Studio. When I deploy it to an clustered IIS6 environment, it works mostly. I can send a request and get a response.
However, the generated metadata consistently refers to a particular node in the cluster and not the clusters virtual name.
https://clustername.test.com/WcfService1/Service1.svc
shows the following in HTML:
Service1 Service
You have created a service.
To test this service, you will need to create a client
and use it to call the service. You can do this using
the svcutil.exe tool from the command line with the
following syntax:
svcutil.exe https://node1.test.com/DocrRetention/Service1.svc?wsdl
which is showing the node name (node1.test.com) rather than the cluster name.
https://clustername.test.com/WcfService1/Service1.svc?wsdl
shows the following xml:
...
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="https://node1.test.com/WcfService1/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="https://node1.test.com/WcfService1/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="https://node1.test.com/WcfService1/Service1.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/WcfService1"/>
</xsd:schema>
</wsdl:types>
...
<wsdl:service name="Service1">
<wsdl:port name="BasicHttpBinding_IService1" binding="tns:BasicHttpBinding_IService1">
<soap:address location="https://node1.test.com/WcfService1/Service1.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Again, showing the node name rather than the virtual host.
So what does my web.config look like? It is small so I'll show the whole thing.
<?xml version="1.0"?>
<configuration>
<system.web>
<customErrors mode="Off"/>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding>
<security mode="Transport"/>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="WcfService1.Service1">
<endpoint binding="basicHttpBinding" contract="WcfService1.IService1"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
As I know URL in WSDL is by default derived from hosting server. Some KB for .NET 3.5 SP1 has introduced new behavior which can use URL from host header. This behavior was also included in .NET 4.0. Check: useRequestHeadersForMetadataAccess. At the end of this article you have some description for this behavior.