在WCF中POST POST Json流

时间:2015-03-26 18:13:01

标签: .net json wcf

我的POST内容类型设置为" application / json"我收到错误当我尝试将json读作流时。这在我使用text / plain

时有效
 <OperationContract()> _ 
 <WebInvoke(UriTemplate:="SaveJsonStream",
 RequestFormat:=WebMessageFormat.Json,
 ResponseFormat:=WebMessageFormat.Json,
 bodystyle:=WebMessageBodyStyle.WrappedRequest)> _ Function
 SaveJsonStream(ByVal str As Stream) As String

 Public Function SaveJsonStream(ByVal str As System.IO.Stream) As String  
 Implements IThirdParty.SaveJsonStream
    Dim strReader As New StreamReader(str)
    Dim data = strReader.ReadToEnd
    Return data
 End Function

这是错误:

<?xml version="1.0" encoding="utf-8"?><HTML><HEAD><STYLE type="text/css">#content{ FONT-SIZE: 0.7em; PADDING-BOTTOM: 2em; MARGIN-LEFT: 30px}BODY{MARGIN-TOP: 0px; MARGIN-LEFT: 0px; COLOR: #000000; FONT-FAMILY: Verdana; BACKGROUND-COLOR: white}P{MARGIN-TOP: 0px; MARGIN-BOTTOM: 12px; COLOR: #000000; FONT-FAMILY: Verdana}PRE{BORDER-RIGHT: #f0f0e0 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #f0f0e0 1px solid; MARGIN-TOP: -5px; PADDING-LEFT: 5px; FONT-SIZE: 1.2em; PADDING-BOTTOM: 5px; BORDER-LEFT: #f0f0e0 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #f0f0e0 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e5e5cc}.heading1{MARGIN-TOP: 0px; PADDING-LEFT: 15px; FONT-WEIGHT: normal; FONT-SIZE: 26px; MARGIN-BOTTOM: 0px; PADDING-BOTTOM: 3px; MARGIN-LEFT: -30px; WIDTH: 100%; COLOR: #ffffff; PADDING-TOP: 10px; FONT-FAMILY: Tahoma; BACKGROUND-COLOR: #003366}.intro{MARGIN-LEFT: -15px}</STYLE>
<TITLE>Request Error</TITLE></HEAD><BODY>
<DIV id="content">
<P class="heading1">Request Error</P>
<BR/>
<P class="intro">The server encountered an error processing the request. The exception message is 'Incoming message for operation 'SaveJsonStream' (contract 'IThirdParty' with namespace 'http://tempuri.org/') contains an unrecognized http body format value 'Json'. The expected body format value is 'Raw'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.'. See server logs for more details. The exception stack trace is:</P>
<P class="intro">   at System.ServiceModel.Dispatcher.HttpStreamFormatter.GetStreamFromMessage(Message message, Boolean isRequest)
   at System.ServiceModel.Dispatcher.HttpStreamFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</P>
</DIV>
</BODY></HTML>

我能做些什么才能让这个工作?我需要允许这样,以便我可以获得第三方发布到服务的数据。

1 个答案:

答案 0 :(得分:0)

在这里查看this文章后,我的最终解决方案。我添加了一个webcontent类型映射器,以允许将json作为文本读取。

Imports System.ServiceModel
Imports System.ServiceModel.Channels

Namespace RestRaw
    Public Class RawContentTypeMapper
        Inherits WebContentTypeMapper

        Public Overrides Function GetMessageFormatForContentType(ByVal contentType As String) As System.ServiceModel.Channels.WebContentFormat
            If contentType.Contains("application/json") Then
                Return WebContentFormat.Raw
            Else
                Return WebContentFormat.Default
            End If
        End Function
    End Class

End Namespace

然后将web.config中的端点绑定添加到customBinding,并将bindingconfiguration设置为rawReceiveCapable。

<services>
  <service behaviorConfiguration="MyProject.NotificationsBehavior" name="MyProject.Notifications" >
    <endpoint address="" binding="customBinding" bindingConfiguration="rawReceiveCapable" contract="MyProject.INotifications" behaviorConfiguration="webBehavior">
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<bindings>
  <customBinding>
    <binding name="rawReceiveCapable">
      <webMessageEncoding webContentTypeMapperType="MyProject.RestRaw.RawContentTypeMapper, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      <httpTransport manualAddressing="true" maxReceivedMessageSize="524288000" transferMode="Streamed" />
    </binding>
  </customBinding>
</bindings>

我在这个端点上为我的解决方案做了这个,只是因为客户端发送到我的服务的数据类型。我建议只在特殊情况下执行此操作,否则您无法手动处理发布数据。