WCF 服务 - 使用 json 调用客户端访问 rest 未提供正确的内容类型

Posted

技术标签:

【中文标题】WCF 服务 - 使用 json 调用客户端访问 rest 未提供正确的内容类型【英文标题】:WCF Service - calling a client to access rest using json is not giving correct content type 【发布时间】:2012-03-22 23:31:52 【问题描述】:

我有一个问题(我已经为此烦恼了好几天),我试图使用 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,然后我还尝试了使用自定义 Web 内容类型映射器的自定义绑定等效项,该映射器强制 Json 内容类型无效。

客户端指向同一台机器上的 Restful 服务(使用 Rest 40 模板)。 有关尝试调用 Rest 端点的 WCf 服务的 web.config,请参见下文:

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

注意:我使用相同功能和配置编写的控制台应用程序确实可以正常工作,并提供正确的内容类型。

感谢您提供的任何帮助。

【问题讨论】:

【参考方案1】:

不确定您是否已经解决了这个问题,但我遇到了同样的问题。 从现有服务调用中调用服务时,您需要将新调用包装在新的 OperationContextScope 中。

您可以在这里查看详细信息:WCF Rest Client sending incorrect content-type

【讨论】:

感谢您提供的信息 - 我最终确实解决了这个问题,这取决于我们的代理遇到了阻碍。我们使用了一个自定义代理(如果我没记错的话),它指定了所需的凭据。幸运的是,这在我们的生产系统中不是问题。

以上是关于WCF 服务 - 使用 json 调用客户端访问 rest 未提供正确的内容类型的主要内容,如果未能解决你的问题,请参考以下文章

WCF REST:返回 JSON 或 XML 以供多个客户端访问?

JSON 中基于 WCF REST 的响应的 JQUERY AJAX

无法从启用 wcf json 的服务向客户端返回嵌套类型

WCF 服务慢速调用取决于调用者

如何创建 PHP SOAP 客户端以在 SSL 下调用 WCF Web 服务?

jQuery - 使用 ajax 调用将 JSON 发送到 WCF 服务为空