How to configure XML web services client to use MessageVersion.Soap11WSAddressing10 for header namespaces. Currently it uses MessageVersion.None namespace, without me able to change it.
You need to do this using a custom WCF binding:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="Soap11Addr10">
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<httpTransport/>
</binding>
</customBinding>
</bindings>
and then reference that custom binding (by name) in your service endpoint:
<services>
<service name="YourAssembly.YourService">
<endpoint name="test"
address=""
binding="customBinding"
bindingConfiguration="Soap11Addr10"
contract="YourAssembly.IYourService" />
</service>
</services>
</system.serviceModel>
If you want to use this from a client, you also need to copy the custom binding configuration to the client's app.config or web.config and reference it there, of course (using Add Service Reference in Visual Studio will do this for you).
Related
I have this configuration for my WCF service which runs on IIS Express port number 50187. The service is hosted on IIS Express of Visual Studio 2017:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="QCConsumerBinding" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="50000000" maxBufferPoolSize="5242880" maxReceivedMessageSize="50000000" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="QCWCFService.QCService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="QCConsumerBinding" contract="QCWCFService.IQCService" />
</service>
<service name="QCWCFService.QCFinalService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="QCConsumerBinding" contract="QCWCFService.IQCFinalService" />
</service>
<service name="QCWCFService.CalibrationService">
<endpoint address="service" binding="netTcpBinding" contract="QCWCFService.ICalibrationService" />
<endpoint address="" binding="wsDualHttpBinding" contract="QCWCFService.ICalibrationService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8080/CalibrationService" />
<add baseAddress="http://localhost:8081/CalibrationService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add scheme="http" binding="wsDualHttpBinding" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
But when I try to run the service it gives this exception:
System.InvalidOperationException: Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].
While I have another application with the same configuration for Dual Http Binding which works perfectly
By default, The IIS express doesn’t support Net.tcp protocol.
The service endpoint with Nettcpbinding requires a base address based on NetTcp protocol.
<endpoint address="service" binding="netTcpBinding" contract="QCWCFService.ICalibrationService" />
Although we provide a Nettcp base address by using the Host Section, It won’t work. This is due to the fact IIS express use self-configuration to provide a base address to run the current project. The configuration of IIS express usually located in the .vs folder of the current Solution, called applicationhost.config
If we run this project in a console application with this configuration, it will work. Thereby we should provide one base address with Nettcp protocol. This can be completed in IIS.
1. Enable windows feature for net.tcp protocol.
2. Add Net.tcp support on the website.
3. Add net.tcp protocol in site binding module.
Please refer to the below for details of adding net.tcp protocol to a website.
WCF ContractFilter Mismatch when enabling Reliable Session
Feel free to let me know if the problem still exists.
I have a WCF Service hosted on a Windows Service that runs on the same network using its own credentials. Security is not important. However, speed and reliability are important.
So, I tried with a netTcpBinding binding. However, I noticed that when I reference the Service into the client. It adds to the configuration file the identity tag with the information of the account that the service is running on:
<identity>
<userPrincipalName value="account#domain" />
</identity>
I really don't want to have this in the client's configuration file, nor I want to pass it programmatically.
When I use instead a basicHttpBinding, I noticed that it does not add this tag. However, I still want to stick with net.tcp. So, my next try was to use a customBinding
So, here is where my problem is. I am not able to reference the custom binding to the client. Can someone verify my configuration? Also. Will this be enough to ignore completely the identity tag? If this is not the proper way, what would be the proper way? Thanks
<system.serviceModel>
<services>
<service name="LicenseServiceLogic.LicenseService">
<endpoint address="net.tcp://localhost:8000/LicenseService"
binding="myCustomBinding"
contract="LicenseServiceLogic.ILicenseService">
</endpoint>
</service>
</services>
<bindings>
<customBinding>
<binding name="myCustomBinding">
<compactMessageEncoding>
<binaryMessageEncoding/>
</compactMessageEncoding>
<tcpTransport listenBacklog ="100"
maxBufferPoolSize ="524288"
maxBufferSize ="2147483647"
maxReceivedMessageSize ="2147483647"/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint binding="customBinding"
bindingConfiguration="myCustomBinding"
contract="IMetadataExchange"
name="http" />
</client>
</system.serviceModel>
First, the reason that we could not reference the custom binding to the client is we should add MEX service endpoint and enable the service metadata behavior. Like below,
<system.serviceModel>
<services>
<service name="VM1.MyService" behaviorConfiguration="mybehavior">
<endpoint address="" binding="netTcpBinding" contract="VM1.IService" bindingConfiguration="mybinding">
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" ></endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:5566"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="mybinding">
<security mode="None"></security>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="mybehavior">
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Besides, if we don’t want to add the identity tag to the client configuration, just we need to do is to set the Security Mode to NONE. As shown above.
For Mex endpoint details.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/metadata
Feel free to let me know if there is anything I can help with.
My server used to communicate only with WCF client, and I added an additional access from the web using REST API. So currently the service's web.config contains two endpoints (one for each):
<services>
<service name="Server.Service">
<endpoint address="" bindingConfiguration="BasicHttpBinding_IServWCF" binding="basicHttpBinding" contract="Server.IWCF" />
<endpoint address="api" behaviorConfiguration="WebBehave" binding="webHttpBinding" contract="Server.IREST" />
</service>
</services>
The WCF client bindings:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IServWCF" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:1862/ServWCF.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServWCF"
contract="WCFServ.IWCF" name="BasicHttpBinding_IServWCF" />
</client>
Everything works OK, and I can access the server's methods from both ways - WCF and HTTP requests.
The problem - I tried to use the Update Service References feature, but it fails. I get the following error message:
The client and service bindings may be mismatched. the remote server returned an error 415
When I remove the new endpoint - behaviorConfiguration="WebBehave", the update service reference works fine. Can I somehow configure the Update References to use a specific end point?
Thanks
This question already has answers here:
WCF NetTcpBinding with mex
(3 answers)
Closed 8 years ago.
I defined a service. It´s service model node in the App.config is:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingConfiguration">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Products.ProductsServiceImpl">
<endpoint address="net.tcp://localhost:8080/Whatever" binding="netTcpBinding"
bindingConfiguration="NetTcpBindingConfiguration" name="NetTcpBinding_IProductsService"
contract="Products.IProductsService" />
</service>
</services>
</system.serviceModel>
But when trying to add the service reference to a client app, I run the service, then I try to add the service reference using the Add Service Reference... dialog, but I can´t locate the service.
If I add an endpoint that uses basicHttpBinding, then the service is localizable via the Add Service Reference dialog.
I tried adding an endpoint that uses mexTcpBinding, but I got an error when trying to start the service, I got an error saying that the contract IMetadataExchange could not be found in the list of contracts implemented by my service.
What could I be missing?
Update:
This service is being opened using the ServiceHost class (an extract of the WPF App that's in charge of starting the service:):
var productsServiceHost = new ServiceHost(typeof(ProductsServiceImpl));
productsServiceHost.Open();
stop.IsEnabled = true;
start.IsEnabled = false;
status.Text = "Service Running";
And I used a WCF Library to create the service (where the service and contract are defined))
Got it!
I used this blog: http://debugmode.net/2010/06/16/nettcpwcfserviceinwindowservice/
The "mex" endpoint should use "mexTcpBinding"
Have to define the host base address, and leave the main endpoint address blank
httpGetEnabled was set to false
Here's the complete service model node (App.config)
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingConfiguration">
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Products.ProductsServiceImpl" behaviorConfiguration="metadataSupport">
<endpoint address="" binding="netTcpBinding"
bindingConfiguration="NetTcpBindingConfiguration" name="NetTcpBinding_IProductsService"
contract="Products.IProductsService" />
<endpoint name="MetaDataTcpEndpoint"
address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8080/Whatever" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataSupport">
<serviceMetadata httpGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
When placing the address in the Add Service Reference... dialog, it should be as:
net.tcp://localhost:8080/Whatever/mex
Although if you have started your service, when pressing Go in the Add Service Reference..., it appends the mex text for you if you haven't
Security mode="none" is usefull to access the service from other machines of the network
Happy coding.
I have an IIS hosted WCF webservice. It started with two consumers.
1) A WinForm test harness in the same solution to test the WCF contracts in the IDE.
2) An Asp.Net Web App that is consuming the published version.
All was working out of the box so to speak.
Then along came the 3rd consumer, an Android app. To get this consuming correctly had to decorate the WCF contracts with JSON WebGets and Webinvokes and alter the WCF Web.config to suit.
Now the original two consumers no longer work. So I need to alter Web.config and / or App.configs to get a configuration where all three work.
Focusing on the IDE first. I have the following service model section for the WCF service Web.Config.
<system.serviceModel>
<client>
<endpoint binding="webHttpBinding" bindingConfiguration="JsonBinding"
contract="CouponParkingWCF.ICouponService" name="Json"
kind="" endpointConfiguration="">
<identity>
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
<endpoint address="http://localhost:8707/CouponParking.svc"
binding="basicHttpBinding" contract="CouponParkingWCF.ICouponService"
name="BasicHttpBinding_ICouponService" />
</client>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" />
</basicHttpBinding>
<webHttpBinding>
<binding name="JsonBinding" />
</webHttpBinding>
</bindings>
<services>
<service name="CouponParkingWCF.CouponService">
<endpoint behaviorConfiguration="JsonBehavior" binding="webHttpBinding"
bindingConfiguration="" name="jsonEndPoint"
contract="CouponParkingWCF.ICouponService" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="JsonBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="false" />
</system.serviceModel>
The WinForm Test harness App.config has:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttp" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8707/CouponParking.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttp"
contract="CouponParking.ICouponService"
name="BasicHttpBinding_ICouponService" />
</client>
</system.serviceModel>
I am not experienced at configuring endpoints and the above has been based on examples and guesswork.
When I run the Test Harness the wcf Client instantiates but a call on a contract fails with :
There was no endpoint listening at http://localhost:8707/CouponParking.svc
that could accept the message. This is often caused by an incorrect address
or SOAP action. See InnerException, if present, for more details."
The inner exception is :
{"The remote server returned an error: (404) Not Found."}
[System.Net.WebException]: {"The remote server returned an error: (404) Not Found."}
Data: {System.Collections.ListDictionaryInternal}
HelpLink: null
HResult: -2146233079
InnerException: null
Message: "The remote server returned an error: (404) Not Found."
Source: "System"
StackTrace: " at System.Net.HttpWebRequest.GetResponse()\r\n at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)"
TargetSite: {System.Net.WebResponse GetResponse()}
I would appreciate some guidance on what I have got wrong.
Thanks
At a glance, it appears that you've mixed up client endpoints with service endpoints in your service's config file. There's no reason for client endpoints to appear in the service's config file, unless that service is itself calling another service.
Your WinForm's config file is defining a client with basicHttpBinding, but you do not expose a service endpoint with BasicHttpBinding, which is most likely the reason for the error you're getting.
I would try deleting the client endpoints in your service's config file, and add them to the <services> section, like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttp" />
</basicHttpBinding>
<webHttpBinding>
<binding name="JsonBinding" />
</webHttpBinding>
</bindings>
<services>
<service name="CouponParkingWCF.CouponService">
<endpoint address="SOAP"
binding="basicHttpBinding"
contract="CouponParkingWCF.ICouponService"
name="BasicHttpBinding_ICouponService" />
<endpoint address="JSON"
binding="webHttpBinding" bindingConfiguration="JsonBinding"
contract="CouponParkingWCF.ICouponService" name="Json"
kind="" endpointConfiguration="">
<identity>
<certificateReference storeName="My" storeLocation="LocalMachine"
x509FindType="FindBySubjectDistinguishedName" />
</identity>
</endpoint>
</service>
</services>
Remember the ABC's of WCF: A = Address, B = Binding and C = Contract - those three items define a service.
Since you added a client that needed a different binding then your test harness or your ASP.NET application, you need to expose a second endpoint with that binding.
EDITED
As #marc_s pointed out, you'll need two distinct relative addresses. I've updated the config file to reflect that.
I've not had an occasion to use multiple endpoints myself, but I believe you'd use them this way, with the base address being provided by the location of the *.svc file:
http://localhost:8707/CouponParking.svc/SOAP
http://localhost:8707/CouponParking.svc/JSON
With the first being for the BasicHttpBinding and the second being for the WebHttpBinding.
You basically just need two separate endpoints to provide both the basicHttpBinding (a SOAP binding) and the webHttpBinding for your Android client (a REST binding).
The "base" address of your service is defined by your IIS virtual directory and where the *.svc file lives (http://localhost:8707/CouponParking.svc) - so both services will be reachable at this "base" address plus any relative address defined
So you need to configure this something like this:
<services>
<service name="CouponParkingWCF.CouponService">
<!-- define the basicHttp (SOAP) endpoint at the base address -->
<endpoint name="SoapEndpoint"
address=""
binding="basicHttpBinding"
contract="CouponParkingWCF.ICouponService" />
<!-- define the REST endpoint at (base)+"/rest" -->
<endpoint name="RestEndpoint"
address="rest"
behaviorConfiguration="JsonBehavior"
binding="webHttpBinding"
contract="CouponParkingWCF.ICouponService" />
</service>
</services>
With this setup, you should be able to call your service using the basicHttpBinding (SOAP) at
http://yourServer:8707/CouponParking.svc
and you should be able to access the REST-based, JSON-enabled endpoint at
http://yourServer:8707/CouponParking.svc/rest
Both server-side endpoints will be handled by the same service code - it's just the endpoint (and the protocols that endpoints understands) that are different