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