i have an issue (of which i've been pulling my hair out for a number of days) whereby I'm attempting to use a WCF service to call another RESTful service.
however, when tracing this through it fails to put the correct json content type on the message.
example of call in client (this is within a WCF service which calls the code)
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior()]
public partial class MyRestServiceClient : System.ServiceModel.ClientBase<IMyRestService>, IMyRestService
{
[WebInvoke(Method = "POST", UriTemplate = "/MyService/ReferenceTypes.json", RequestFormat = WebMessageFormat.Json)]
public MyServiceLists GetReferenceTypes()
{
try
{
return base.Channel.GetReferenceTypes();
}
catch (Exception e)
{
throw e; //throws exception here - method not allowed
}
}
}
Instead of putting content type of application/json it places application/xml instead to the call. this was worked out from the activity tracing placed on the WCF service doing the call. example of the "message sent" info from Activity log:
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>262164</EventID>
<Type>3</Type>
<SubType Name="Information">0</SubType>
<Level>8</Level>
<TimeCreated SystemTime="2012-03-05T12:26:52.8913972Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{7759c13c-972d-46a2-8048-2dcaf1c066bf}" />
<Execution ProcessName="aspnet_wp" ProcessID="2408" ThreadID="11" />
<Channel />
<Computer>Z1020734</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Information">
<TraceIdentifier>http://msdn.microsoft.com/en-GB/library/System.ServiceModel.Channels.MessageSent.aspx</TraceIdentifier>
<Description>Sent a message over a channel.</Description>
<AppDomain>/LM/w3svc/1/ROOT/My.Services-2-129754240054859056</AppDomain>
<Source>System.ServiceModel.Channels.HttpOutput+WebRequestHttpOutput/18905726</Source>
<ExtendedData xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/MessageTraceRecord">
<MessageProperties>
**<Encoder>application/xml; charset=utf-8</Encoder>**
<AllowOutputBatching>False</AllowOutputBatching>
<Via>http://mymachine/My.services.stub.REST/</Via>
</MessageProperties>
<MessageHeaders></MessageHeaders>
</ExtendedData>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
I have used a webHttpBinding for the client, then i've also tried the custom binding equivalent with a custom web content type mapper that forces a Json content type to no avail.
the client end point is pointing to a Restful service (using the Rest 40 template) on the same machine. see below for web.config of the WCf service that is trying to call the Rest endpoint:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
</connectionStrings>
<appSettings>
</appSettings>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<services>
<service name="My.Services.MyService" behaviorConfiguration="My.Services.MyServiceBehavior" >
<endpoint address="" binding="customBinding" bindingConfiguration="CustomBinding_IMyService" contract="My.Common.ServiceContracts.IMyService"/>
</service>
<service name="My.Services.SomeOtherService" behaviorConfiguration="My.Services.SomeOtherBehavior" >
<endpoint address="" binding="customBinding" bindingConfiguration="customBinding_ISomeOtherService" contract="My.Common.ServiceContracts.ISomeOtherService"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webHttpCustomBinding">
<security mode="TransportCredentialOnly">
<transport proxyCredentialType="None" clientCredentialType="Windows">
</transport>
</security>
</binding>
</webHttpBinding>
<customBinding>
<binding name ="CustomBinding_IIMyRestService">
<webMessageEncoding webContentTypeMapperType="My.Common.ServiceModel.JsonContentTypeMapper, My.Common" ></webMessageEncoding>
<httpTransport authenticationScheme="Negotiate" ></httpTransport>
</binding>
<binding name="CustomBinding_IMyService">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport maxBufferPoolSize="1000000" maxReceivedMessageSize="1000000"
authenticationScheme="Negotiate" maxBufferSize="1000000" />
</binding>
<binding name="customBinding_ISomeOtherService">
<textMessageEncoding messageVersion="Soap12" />
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://MyMachine/My.services.stub.REST/" binding="customBinding" bindingConfiguration="CustomBinding_IMyRestService" name="RestService" contract="My.Common.ServiceContracts.IIMyRestService" behaviorConfiguration="webhttp"/>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="webhttp">
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="My.Services.MyServiceBehavior">
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="My.Services.SomeOtherServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.net>
<defaultProxy useDefaultCredentials="true"/>
</system.net>
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="c:\temp\my.Services.svclog"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
</configuration>
Note: a console app i've written with the same function and config does work correctly, and gives the correct content type.
Any help you can give is appreciated.