Служба WCF - вызов клиента для доступа к отдыху с использованием json не дает правильного типа контента

у меня есть проблема (из-за которой я рвал на себе волосы в течение нескольких дней), из-за которой я пытаюсь использовать службу WCF для вызова другой службы RESTful.

однако при отслеживании этого через него не удается поместить в сообщение правильный тип содержимого json.

пример вызова в клиенте (это внутри службы WCF, которая вызывает код)

[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 
        }
    }
}

Вместо того, чтобы помещать тип содержимого application/json, он помещает application/xml вместо вызова. это было получено из трассировки активности, размещенной в службе WCF, выполняющей вызов. пример информации об отправленном сообщении из журнала активности:

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

Я использовал webHttpBinding для клиента, затем я также попробовал эквивалент пользовательской привязки с пользовательским сопоставителем типов веб-контента, который принудительно использует тип контента Json безрезультатно.

конечная точка клиента указывает на службу Restful (с использованием шаблона Rest 40) на том же компьютере. см. ниже файл web.config службы WCf, которая пытается вызвать конечную точку Rest:

<?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>

Примечание: консольное приложение, которое я написал с той же функцией и конфигурацией, работает правильно и дает правильный тип контента.

Любая помощь, которую вы можете оказать, приветствуется.


person williamfalconeruk    schedule 05.03.2012    source источник


Ответы (1)


Не уверен, что вы уже решили эту проблему, но я столкнулся с той же проблемой.
При вызове службы из существующего вызова службы вам необходимо обернуть новый вызов в новую OperationContextScope.

Подробнее см. здесь: Клиент WCF Rest отправляет неверный тип содержимого

person user1759444    schedule 19.10.2012
comment
спасибо за информацию - в конце концов я решил эту проблему, это было связано с тем, что наш прокси мешал. мы использовали собственный прокси (если я правильно помню), который указал необходимые учетные данные. К счастью, это не было проблемой в нашей производственной системе. - person williamfalconeruk; 15.05.2014