webHttpBinding using webMessageEncoding: how to configure? - wcf

I have a REST WCF service. Its using a webHttpBinding and the configuration looks like this:
<service name="IndexingService.RestService" behaviorConfiguration="IndexingService.Service1Behavior">
<endpoint
address=""
binding="webHttpBinding"
bindingConfiguration="CustomMapper"
contract="IndexingService.IIndexingService"
behaviorConfiguration="webby"/>
</service>
The CustomMapper is used to apply a custom WebContentTypeMapper, which I tried to configure like this:
<binding name="CustomMapper">
<webMessageEncoding webContentTypeMapperType="IndexingService.CustomContentTypeMapper, IndexingService" />
<httpTransport manualAddressing="true" />
</binding>
But I cannot figure out where in my web.config I should insert these lines:
If I put these lines below I get an error, because webMessageEncoding is not a recognized element.
If I put the lines below a custom binding tag, I get an error that wsHttpBinding does not have a CustomMapper defined!?
Can somebody explain how to use a custom type mapper together with webHttpBinding?

If you define a complete custom binding (as you do here with CustomMapper):
<binding name="CustomMapper">
<webMessageEncoding webContentTypeMapperType=
"IndexingService.CustomContentTypeMapper, IndexingService" />
<httpTransport manualAddressing="true" />
</binding>
then you need to use that custom binding in your service endpoint - not webHttpBinding! This config section does not define just a bindingConfiguration!
Try this config here:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomMapper">
<webMessageEncoding webContentTypeMapperType=
"IndexingService.CustomContentTypeMapper, IndexingService" />
<httpTransport manualAddressing="true" />
</binding>
</customBinding>
</bindings>
<services>
<service name="IndexingService.RestService"
behaviorConfiguration="IndexingService.Service1Behavior">
<endpoint
address=""
binding="customBinding"
bindingConfiguration="CustomMapper"
contract="IndexingService.IIndexingService"
behaviorConfiguration="webby"/>
</service>
</services>
</system.serviceModel>
Marc

Related

How to use netTcpBinding and netMsmqBinding together?

I am trying to use both tcp as well as msmq but it gives an error msmq doesn't support dual binding or it's not properly configured, how to solve this issue?
I have created two end points.
I tried to do something like this
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="Binding_Config" receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:02:30">
<security mode="None">
<transport clientCredentialType ="None" protectionLevel="None"></transport>
<message clientCredentialType="None"/>
</security>
</binding>
</netTcpBinding>
<netMsmqBinding>
<binding name="ServiceBinding" durable="true" exactlyOnce="true" useActiveDirectory="false" receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:02:30" >
<security mode="None">
<transport
msmqAuthenticationMode="None"
msmqProtectionLevel="None"
/>
</security>
</binding>
</netMsmqBinding>
</bindings>
<services>
<service name="WCFLib.SignalService"
behaviorConfiguration = "SignalServiceMEXBehavior">
<endpoint address ="TradeSignalService"
binding="netTcpBinding"
contract="TradeServiceLib.ITradeSignalService" bindingConfiguration="Binding_Config"/>
<!-- Enable the MEX endpoint -->
<!-- Need to add this so MEX knows the address of our service -->
<endpoint address="net.msmq://localhost/private/FirstQueue" binding="netMsmqBinding" contract="TradeServiceLib.ITradeSignalService" bindingConfiguration="ServiceBinding"/>
<!--<endpoint address="mex" binding="netTcpBinding" contract="IMetadataExchange"/>-->
<host>
<baseAddresses>
<add baseAddress ="http://192.168.1.125:2344"/>
<add baseAddress ="net.tcp://192.168.1.125:2348"/>
</baseAddresses>
</host>
</service>
</services>
<!-- A behavior definition for MEX -->
<behaviors>
<serviceBehaviors>
<behavior name="SignalServiceMEXBehavior" >
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<connectionStrings>
<clear />
</connectionStrings>
</configuration>
I am not sure where I am wrong.
I don't know why but this site needs more text from me so typing this line, please ignore this I don't know why but this site needs more text from me so typing this line, please ignore this I don't know why but this site needs more text from me so typing this line, please ignore this I don't know why but this site needs more text from me so typing this line, please ignore this I don't know why but this site needs more text from me so typing this line, please ignore this
Those two bindings are very different. You need two endpoints for the same service exposed at different addresses and set up with different bindings.
See this MSDN article for more information on this.
As an example:
<service
name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<!-- This endpoint is exposed at the base address provided by host:
http://localhost/servicemodelsamples/service.svc -->
<endpoint address=""
binding="basicHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<!-- secure endpoint exposed at {base address}/secure:
http://localhost/servicemodelsamples/service.svc/secure -->
<endpoint address="secure"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
...
</service>

WCF timeouts in SOME solutions

The problem is that when I create a new solution in VS2012 and add service reference of wcf, everything works fine. However, when I add the same service reference to one of my projects, the methods receive timeout exception. The problem might be that when I add the reference to my project, visual studio didn't create the codes until I uncheck the option "Reuse types in referenced assemblies". I checked configuration files but see no difference at all. I include a part of config file anyway:
<system.serviceModel>
<client>
<endpoint address="url"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService"
contract="NewsBannersCampaignService.IService" name="BasicHttpBinding_IService" />
</client>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService" />
</basicHttpBinding>
<wsHttpBinding>
<binding name="DefaultBinding">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="DefaultBehavior" name="project.Services.Integration">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="DefaultBinding" name="Integration" contract="project.Services.IIntegration" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Edit: For anyone that may have this problem; the problem in my case was I forgot to delete my defaultProxy setting in config file. After deleting it everything worked fine. I just deleted
<system.net>
<defaultProxy>
<proxy proxyaddress="http://address" bypassonlocal="True" />
</defaultProxy>
</system.net>

Deploying a WCF service that uses netTcpBinding (not IIS hosted)

I'm developing a client-server app using WCF over the netTcpBinding.
My solution has 2 projects, the client one and the server one.
So far I've learnt that in order to get the WCF service working I have to do some configuration on the app.config file. This I did and things are working fine.
But now I have a problem finding out what to do when I deploy the service to a server, in order for the client to connect. My problem is that I don't know what I have to modify in the app.config (or any other location) when I deploy the service in to a location other than "localhost".
Here is my server app's app.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<system.serviceModel>
<services>
<service name="MMServidor3.ServidorCliente">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="MMServidor3.iServicioMM">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:4005/MMServidor3/" />
<add baseAddress="net.tcp://localhost:4006/MMServidor3/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The "mex" endpoint and the http protocol base address are there in order for the client to get the metadata (I couldn't get it otherwise).
So, since I don't know beforehand what the IP address is where I'm going to deploy the server, I'd like the endpoint be read from a config or ini file (I would rather not have to compile for each endpoint).
Also, what do I have to modify on the client side? Here is the relevant section of the client app.config:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_iServicioMM" 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="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:4006/MMServidor3/" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_iServicioMM" contract="MMServicioServidor.iServicioMM"
name="NetTcpBinding_iServicioMM">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
Any advice would be appreciated!
Config files are specific to an environment. Typically, you'll change (if needed) the localhost bit in service addresses to an IP address or name.
For clients it's the same. A production-client should be configured in its production environment to use the URL of the production service. Of course you can't configure the client until you know where the service will be located*.
Unfortunately you'll have to specify the URL for each client endpoint individually, for more info have a look at this related question. One alternative you could work out, is implementing your own setting for a client side "BaseAddress", and use that to programmatically specify endpoint addresses.
* If you're after some more extreme flexibility in locating services and clients, you could look into WCF Discovery mechanisms.
** As another side note, if you're looking to automate creating config files for different environments I can recommend using (for example) SlowCheetah.

How do you configure a WCF service with two endpoints to use a different ListenUri for each endpoint?

I have a WCF Service which exposes an endpoint using the webHttpBinding and is consumed by both WPF and ASP.NET applications. Everything works great.
I am now attempting to consume the service from Windows Phone (WP7). However, as the .NET Framework hasn't quite caught up to WP7 yet, the System.ServiceModel.Web namespace is unavailable with the result that the webHttpBinding doesn't work in WP7.
Now, on my service, if I switch the webHttpBinding out for a basicHttpBinding, the phone application works.
I do not want to have to rework my WPF and ASP.NET applications to use the basicHttpBinding though.
I understand that WCF is capable of supporting multiple bindings and I have attempted to configure and run the service so that it exposes endpoints for both webHttpBinding and basicHttpBinding. The service appears to start up fine. However, the WPF & ASP.NET applications are unable to access it. And when I attempt to create a Service Reference in the WP7 application I get the following message:
A binding instance has already been associated to listen URI
'http://localhost:1726/GeneralService.svc'. 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.
A colleague and I have played around with a variety of changes to the baseAddress, address, and listenUri attributes without any luck. We are now at the point of just trial and error which isn't proving to be very effective.
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="generalBasic" />
</basicHttpBinding>
<webHttpBinding>
<binding name="general" maxReceivedMessageSize="2147483647">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" />
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="MyProject.GeneralService">
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="generalBasic"
contract="MyProject.Contracts.IGeneralService" />
<endpoint behaviorConfiguration="web"
binding="webHttpBinding"
bindingConfiguration="general"
contract="MyProject.Contracts.IGeneralService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:1726/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
Just specify the address attribute with a value for either basic or webhttp endpoint that would distinguish its address. Ex:
<endpoint behaviorConfiguration="web" address="rest" binding="webHttpBinding" bindingConfiguration="general" contract="MyProject.Contracts.IGeneralService" />
should resolve your problem
When defining your endpoints for the first one you are specifying address="" and for second you dont have any value(So even for this one we will have address as "")
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="generalBasic"
contract="MyProject.Contracts.IGeneralService" />
<endpoint behaviorConfiguration="web"
binding="webHttpBinding"
bindingConfiguration="general"
contract="MyProject.Contracts.IGeneralService" />
So in that case when we specify address as empty it will take default base address.
So try to specify some value for anyone of the endpoints. So that we will have different address for these 2 endpoints.
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="generalBasic"
contract="MyProject.Contracts.IGeneralService" />
<endpoint behaviorConfiguration="web" address="WP7Service"
binding="webHttpBinding"
bindingConfiguration="general"
contract="MyProject.Contracts.IGeneralService" />
So our new endpoints address are:
http://localhost:1726/GeneralService.svc
http://localhost:1726/GeneralService.svc/WP7Service
For usage service on WP you should expose your service with Rest, Soap or OData endpoints. In the link below it is quite clear described how to expose WCF RIA for such purposes: Exposing WCF (SOAP\WSDL) Services
It works great for me.
What I was missing was protocolMapping for both endpoints:
<configuration>
<!--...-->
<system.serviceModel>
<!--...-->
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" bindingConfiguration="BasicHttpBindingConfiguration"/>
<add binding="basicHttpsBinding" scheme="https" bindingConfiguration="SecureHttpBindingConfiguration"/>
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBindingConfiguration" />
<binding name="SecureHttpBindingConfiguration" >
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="Namespace.ServiceName">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBindingConfiguration"
contract="Namespace.IServiceName" />
</service>
<service name="Namespace.ServiceName">
<endpoint address="" binding="basicHttpsBinding" bindingConfiguration="BasicHttpsBindingConfiguration"
contract="Namespace.IServiceName" />
</service>
</services>
<!--...-->
</system.serviceModel>
<!--...-->
</configuration>

Customize a WCF RIA Services Endpoint

Is it possible to customize the parameters of a WCF RIA Services endpoint? Specifically, I would like to create a custom binding for the endpoint and increase the maxReceivedMessageSize to allow sending the contents of a file that is a few megabytes in size.
I've tried meddling in the web.config, but I'm getting the following error:
[InvalidOperationException]: The
contract name MyNamespace.MyService
could not be found in the list of
contracts implemented by the service
MyNamespace.MyService
web.config
<system.serviceModel>
<bindings>
<customBinding>
<binding name="CustomBinaryHttpBinding">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</customBinding>
</bindings>
<services>
<service name="MyNamespace.MyService">
<endpoint address="" binding="wsHttpBinding" contract="MyNamespace.MyService" />
<endpoint address="/binary" binding="customBinding" bindingConfiguration="CustomBinaryHttpBinding" contract="MyNamespace.MyService" />
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
We had a similar problem - we want to send large bitmaps fom Silverlight client to Server using WCF-RIA service invoke operation.
The following change in Web.config worked for us:
<httpRuntime requestValidationMode="2.0" maxRequestLength="6225920"/>
See How to configure Parameter/Message length for WCF-RIA-Service operation