1
votes

I am experiencing issues getting json into my WCF REST service.

<ServiceContract()>
Public Interface IMyService

    <OperationContract()>
    <WebInvoke(Method:="POST",
    RequestFormat:=WebMessageFormat.Json,
    ResponseFormat:=WebMessageFormat.Json,
    UriTemplate:="notify",
    BodyStyle:=WebMessageBodyStyle.Bare)>
    Sub Notify(message As String)

End Interface

...
      <service name="MyService" behaviorConfiguration="ServiceBehavior">
        <endpoint binding="webHttpBinding" behaviorConfiguration="webHttp" bindingConfiguration="webBinding" contract="IMyService" />
      </service>
      ...
      <endpointBehaviors>
        <behavior name="webHttp">
          <webHttp  />
        </behavior>
      </endpointBehaviors>
...

When I POST to my service at http://localhost:64574/MyService.svc/notify with the payload:

{ "Id" : "123456789", "Code" : "1", "ExId" : "123456789", "title" : "Title", "message" : "Sample Message" }

I get the error below.

The server encountered an error processing the request. The exception message is 'There was an error deserializing the object of type System.String. End element 'root' from namespace '' expected. Found element 'Id' from namespace ''.'. See server logs for more details. The exception stack trace is:

at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver) at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName) at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.ReadObject(Message message) at System.ServiceModel.Dispatcher.SingleBodyParameterDataContractMessageFormatter.ReadObject(Message message) at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.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.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

EDIT: Ideally I would like to get the raw json from the request body using OperationContext.Current.RequestContext.RequestMessage but it seems I can only get xml. When I use JsonConvert.SerializeXmlNode(doc) I get json but not the raw json I expect.

1
Have you tried BodyStyle WebMessageBodyStyle.Wrapped ? - lcryder
Sorry, meant WebMessageBodyStyle.WrappedRequest - lcryder
Yes, I tried that. WebMessageBodyStyle.WrappedRequest or WebMessageBodyStyle.Wrapped returns me "Sample Message". I need the whole json object. - Eric

1 Answers

1
votes

You could use System.IO.Stream as parameter.

Example:

WCF Service Interface:

<ServiceContract()>
Public Interface IService1
  <OperationContract()>
  Sub NotifyStream(jsonStream As Stream)
End Interface

WCF Service Implementation:

Public Class Service1 Implements IService1
  Public Sub NotifyStream(jsonStream As Stream) Implements IService1.NotifyStream
        Dim jsonString = ""
        Using reader As New StreamReader(jsonStream, Encoding.UTF8)
            jsonString = reader.ReadToEnd
        End Using
        'Do something with jsonString'
  End Sub
End Class

WCF Client:

Dim client = New Service1Client
Dim jsonString = "{ 'Id' : '123456789', 'Code' : '1', 'ExId' : '123456789', 'title' : 'Title', 'message' : 'Sample Message' }"
Dim stream = New MemoryStream(Encoding.UTF8.GetBytes(jsonString))
client.NotifyStream(stream)

Documentation: