首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WCF IErrorHandler Get请求消息

WCF IErrorHandler Get请求消息
EN

Stack Overflow用户
提问于 2016-03-17 13:35:15
回答 3查看 1.4K关注 0票数 2

(类似于问题,但在这种情况下最终不需要它)

我正在使用一个IErrorHandler实现--创建一个FaultException,以便服务的客户端在发生未处理异常时接收“漂亮”错误。

现在,我想在请求消息中使用一个元素,并在FaultException中将其弹出,但我没有获胜。

我可以访问OperationContext.Current.RequestContext.RequestMessage,并且可以使用它的ToString()看到完整的信封(包括我希望FaultResponse包含的'message‘属性),但是我想要’手动‘反序列化请求消息,或者甚至只是将主体读取为XML,以便提取我正在寻找的请求属性。

但是,我无法从消息中读取,因为(我假设)消息已经在WCF管道中的某个地方读取了:

‘消息无法支持操作,因为它已被复制’

下面是我的ProvideFault()实现(我知道XElement解析在这种形式下甚至不起作用--我现在不关注这个问题):

代码语言:javascript
复制
public void ProvideFault(Exception error, MessageVersion version, ref Message fault) {
    if (error is FaultException)
    {
        // Let WCF handle            
    }
    else
    {
        // Extract the 'messageID' element from the request message
        var req = OperationContext.Current.RequestContext.RequestMessage;

        // Throws the 'has been copied' exception
        XElement body = XElement.Parse(XElement.ReadFrom(req.GetReaderAtBodyContents()).ToString()); 

        var msgId = (string)body.Descendants("messageID").FirstOrDefault();

        var err = new FaultException<Foo>(new Foo
            {
                MessageID = msgId
            }, "Server error");

        var msgFault = err.CreateMessageFault();
        fault = Message.CreateMessage(
            version,
            msgFault,
            null);
    } }

做这件事最好的方法是什么?

编辑:看上去不可能在IErrorHandler事件期间读取OperationContext的请求消息--大概是因为它已经在IErrorHandler管道中被读取了(因此使用MessageBuffer创建消息副本将无法工作)。这个问题的“解决办法”在公认的答案中描述了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-03-17 19:17:22

一种可能的方法是使用IDispatchMessageInspector从请求消息中读取所需的值,并将它们存储在OperationContext中,直到需要访问它们为止。

用于IDispatchMessageInspector的MSDN文档是笔直的。只需记住在读取消息之前先创建消息的缓冲副本。

代码语言:javascript
复制
public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext)
{
    var bufferedCopy = request.CreateBufferedCopy(2000000); // choose a suitable buffer size
    request = bufferedCopy.CreateMessage();// Message for continued processing

    var messageToRead = bufferedCopy.CreateMessage(); // message to read properties from

    return null;
}

有关如何将属性附加到问题上,请参阅此OperationContext。

票数 4
EN

Stack Overflow用户

发布于 2016-03-17 17:11:16

您应该复制原始消息的缓冲区:

代码语言:javascript
复制
// Read orignal messagem
var originalMessage = OperationContext.Current.RequestContext.RequestMessage;

// Copy message
MessageBuffer buffer = originalMessage.CreateBufferedCopy(Int32.MaxValue);
//OperationContext.Current.RequestContext.RequestMessage = buffer.CreateMessage();

var req = buffer.CreateMessage();
XElement body = XElement.Parse(XElement.ReadFrom(req.GetReaderAtBodyContents()).ToString());

希望能帮上忙。

票数 1
EN

Stack Overflow用户

发布于 2016-03-17 13:58:58

您应该自定义异常并使用它的属性来保持Id

代码语言:javascript
复制
public void ProvideFault(Exception error, MessageVersion version, ref Message fault) 
{
    var myException = error as MyException;
    if (myException == null)
    {
        return;           
    }

    var err = new FaultException<Foo>(new Foo
        {
            MessageID = myException.MsgId
        }, "Server error");

    var msgFault = err.CreateMessageFault();
    fault = Message.CreateMessage(
        version,
        msgFault,
        null);
} 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36062138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档