WCF OperationFormatter遇到无效的消息正文

时间:2018-12-12 11:14:46

标签: c# wcf

我有一项任务将wcf项目合并到Web api项目中。我已经将.svc文件和svc.cs文件以及web.config的一部分复制到了Web api项目中,更新了服务名称,以便它们引用Web api项目中的svc文件,并引用了端点来引用普通项目。

正在构建Web api项目,我通过输入服务之一的路径来测试WCF服务是否正常工作: http://localhost/WebAPI_Interface/Test.svc 这会提供一个网页,通知我已经创建了服务(因此没有配置错误)。

我想测试服务操作之一getavailablelibraries。运营合同如下:

[OperationContract(Action = "getavailablelibraries")]
[WebInvoke(Method = "POST", UriTemplate = "getavailablelibraries", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
Libraries getavailablelibraries(SystemAuthentication auth);

在提琴手中,我设置了一个POST请求以: http://localhost/WebAPI_Interface/Test.svc/getavailablelibraries

,带有标头:Content-Type:application / json 和邮件正文:

{
"auth": {
      "username" : "Test",
      "password" : "Test",
      "systemname" : "Test"
  }
}

执行此请求将返回504错误。我打开WCF跟踪,发现在处理消息时抛出以下异常:

OperationFormatter遇到无效的消息正文。预期找到名称为“ root”且名称空间为“''的节点类型“元素”。找到名称为“”和名称空间为“

”的节点类型“ None”

在提琴手中,当我在旧的WCF服务上尝试相同的请求时,它以200成功。

如果我重试相同的请求,但是这次没有消息正文,则这次我发现它在getavailablelibraries的调试器中爆发,并且auth变量设置为null。因此,将json反序列化到SystemAuthentication类中似乎是一个问题,但是,相同的json在原始WCF项目上也起作用,所以我很茫然。

有什么想法吗?

编辑: 我尝试将Namespace和Name属性添加到ServiceContract和DataContract,但是仍然出现相同的错误。 我切换了BodyStyle = WebMessageBodyStyle.Bare,这导致了另一个错误:

无法使用DataContractSerializer反序列化具有根名称“和根名称空间”(用于操作“ getavailablelibraries”和协定(“ ProcessExport”,“ http://www.myurl.com/services”)的XML正文)。确保将与XML对应的类型添加到服务的已知类型集合中。

当我将BodyStyle更改为Bare时,原始的wcf服务也将停止工作: 数据合同类型'Services.SystemAuthentication'无法反序列化,因为未找到所需的数据成员'password,systemname,username'。

更多信息,错误的堆栈跟踪:

  

在   System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.ValidateTypeObjectAttribute(XmlDictionaryReader   阅读器,布尔值isRequest)位于   System.ServiceModel.Dispatcher.DataContractJsonSerializerOperationFormatter.DeserializeBody(XmlDictionaryReader   阅读器,MessageVersion版本,字符串操作,MessageDescription   messageDescription,Object []参数,布尔值isRequest)位于   System.ServiceModel.Dispatcher.OperationFormatter.DeserializeBodyContents(消息   消息,Object []参数,布尔值isRequest)位于   System.ServiceModel.Dispatcher.OperationFormatter.DeserializeRequest(消息   消息,Object []参数)在   System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(消息   消息,Object []参数)在   System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(消息   消息,Object []参数)在   System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(消息   消息,Object []参数)在   System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&   rpc)   System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&   rpc)位于System.ServiceModel.Dispatcher.MessageRpc.Process(布尔   isOperationContextSet)   System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext   请求,布尔值cleanThread,OperationContext   currentOperationContext)   System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext   请求,OperationContext currentOperationContext)位于   System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult   结果)   System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult   结果)   System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult   结果)   System.ServiceModel.Diagnostics.TraceUtility。<> c__DisplayClass14_0。 b__0(AsyncCallback   回调,IAsyncResult结果)   System.Runtime.AsyncResult.Complete(布尔值已同步完成)在   System.Runtime.InputQueue 1.AsyncQueueReader.Set(Item item) at System.Runtime.InputQueue 1.EnqueueAndDispatch(项目,布尔值   canDispatchOnThisThread)在   System.Runtime.InputQueue 1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread) at System.ServiceModel.Channels.SingletonChannelAcceptor 3.Enqueue(QueueItemType   项,动作为dequeuedCallback,布尔值canDispatchOnThisThread)位于   System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.CompleteParseAndEnqueue(IAsyncResult   结果)   System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.HandleParseIncomingMessage(IAsyncResult   结果)在System.Runtime.AsyncResult.SyncContinue(IAsyncResult   结果)   System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult..ctor(ReplyChannelAcceptor   接受者,动作dequeuedCallback,HttpPipeline管道,   AsyncCallback回调,对象状态)位于   System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor   replyChannelAcceptor,Action dequeuedCallback,AsyncCallback回调,   对象状态)   System.ServiceModel.Channels.HttpChannelListener 1.HttpContextReceivedAsyncResult 1.ProcessHttpContextAsync()   在   System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext   上下文,Action acceptorCallback,AsyncCallback回调,对象   州)   System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult   结果)   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()   在   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()   在   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(对象   州)   System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback   回调,对象状态)   System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object   州)   System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32   errorCode,UInt32 numBytes,NativeOverlapped * nativeOverlapped)位于   System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32   错误,UInt32 bytesRead,NativeOverlapped * nativeOverlapped)位于   System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32   errorCode,UInt32 numBytes,NativeOverlapped * pOVERLAP)

1 个答案:

答案 0 :(得分:0)

该问题原来是由于消息处理程序可能引发了异常。 在Web api项目的Startup.Config中,我们有一行: config.MessageHandlers.Add(new MessageLoggingHandler(ref globalLogger));

此MessageLoggingHandler类继承自Microsoft类DelegatingHandler,并在进行Web api调用时重写SendAsync函数以进行一些日志记录。如果请求Uri包含“ .svc /”,则我们进行了检查并调用基类定义,并且它开始工作,因此推测日志记录代码特定于Web api请求。