【发布时间】:2014-03-11 22:32:21
【问题描述】:
当我使用无效的操作请求调用我的 WCF 服务时,我遇到了一个异常。我需要将此异常作为 FaultException 发送。
我尝试了以下场景:-
我使用了
IErrorHandler,但ProvideFault函数在此服务调用中没有命中(在其他情况下它工作正常)。-
我也使用消息检查器来处理异常。但
AfterReceiveRequest和BeforeSendReply在此调用期间也没有命中。如何将所有类型的异常作为 FaultException 发送
服务请求
请求: POST /0710 HTTP/1.1
标题: 连接:关闭 内容长度:11 内容类型:application/soap+xml;字符集=utf-8; action="无效:S.O.A.P.:Action..." 主机:userpc:9001
正文:
发生异常(来自跟踪日志)
异常类型
System.ServiceModel.CommunicationException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
留言
无法识别的消息版本。
堆栈跟踪
System.ServiceModel.Channels.ReceivedMessage.ReadStartEnvelope(XmlDictionaryReader reader)
System.ServiceModel.Channels.BufferedMessage..ctor(IBufferedMessageData messageData, RecycledMessageState recycledMessageState, Boolean[] understoodHeaders, Boolean understoodHeadersModified)
System.ServiceModel.Channels.BufferedMessage..ctor(IBufferedMessageData messageData, RecycledMessageState recycledMessageState)
System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.ReadMessage(ArraySegment`1 buffer, BufferManager bufferManager, String contentType)
System.ServiceModel.Channels.HttpInput.DecodeBufferedMessage(ArraySegment`1 buffer, Stream inputStream)
System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.ContinueReading(Int32 bytesRead)
System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.DecodeBufferedMessageAsync()
System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.BeginParse()
System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult..ctor(HttpRequestMessage httpRequestMessage, HttpInput httpInput, AsyncCallback callback, Object state)
System.ServiceModel.Channels.HttpInput.BeginParseIncomingMessage(HttpRequestMessage httpRequestMessage, AsyncCallback callback, Object state)
System.ServiceModel.Channels.HttpInput.BeginParseIncomingMessage(AsyncCallback callback, Object state)
System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginParseIncomingMessage(AsyncCallback asynCallback, Object state)
System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult..ctor(ReplyChannelAcceptor acceptor, Action dequeuedCallback, HttpPipeline pipeline, AsyncCallback callback, Object state)
System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor, Action dequeuedCallback, AsyncCallback callback, Object state)
System.ServiceModel.Channels.HttpRequestContext.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor, Action acceptorCallback, AsyncCallback callback, Object state)
System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1.ProcessHttpContextAsync()
System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1..ctor(HttpRequestContext requestContext, Action acceptorCallback, HttpChannelListener`1 listener, AsyncCallback callback, Object state)
System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext context, Action acceptorCallback, AsyncCallback callback, Object state)
System.ServiceModel.Channels.SharedHttpTransportManager.EnqueueContext(IAsyncResult listenerContextResult)
System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult listenerContextResult)
System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.Net.LazyAsyncResult.Complete(IntPtr userToken)
System.Net.ListenerAsyncResult.IOCompleted(ListenerAsyncResult asyncResult, UInt32 errorCode, UInt32 numBytes)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
您可以通过使用以下代码调用任何 WCF 服务来创建类似的情况
public static string HttpPost(string URI)
{
try
{
var r = (HttpWebRequest) WebRequest.Create(URI);
r.Method = "POST";
r.ContentType = @"application/soap+xml; charset=utf-8; action=""Invalid:S.O.A.P.:Action...""";
var ws = new StreamWriter(r.GetRequestStream());
ws.Write("<EmptyXml/>");
ws.Close();
var resp = (HttpWebResponse) r.GetResponse();
var sr = new StreamReader(resp.GetResponseStream());
return sr.ReadToEnd();
}
catch (FaultException ex)
{
//I need to catch low level exception as Fault exception
}
catch (CommunicationException ex)
{
}
catch (Exception ex)
{
Console.WriteLine("Exception : " + ex.Message);
}
return null;
}
【问题讨论】:
-
您在哪里托管您的服务? WAS、IIS、WinService、WPF/Winforms?如果是 WPF/Winforms,您可能忘记在服务行为或回调行为中使用 (UseSynchronizationContext=False)。
-
我正在使用 WCF 服务库,它是从 WPF 应用程序启动的。我已经在使用该属性。我在服务中使用的属性是 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single , ConfigurationName = "xxxxx", InstanceContextMode = InstanceContextMode.Single, Name = "xxxxx", Namespace = "xxxx.xx.xx", UseSynchronizationContext = false)]
-
你在某处使用回调吗?
-
我没有在这个服务中使用回调
-
你能提供更多关于你正在尝试的代码吗?