3

这是我理想中想要做的

    public void AfterReceiveReply(ref Message reply, object correlationState) 
    {
        if (reply.IsFault)
        {
            FaultException exp = reply.GetBody<FaultException>();
            if (exp.Code.Name == "MyFaultCode")
            {
               //Do something here
            }
        }
    } 

但我得到了这个例外

第 1 行位置 82 出错。从命名空间“ http://schemas.datacontract.org/2004/07/System.ServiceModel ”中期待元素“FaultException” 。遇到名称为“Fault”的“元素”,命名空间“ http:/ /schemas.xmlsoap.org/soap/envelope/ '。

当我尝试做

FaultException exp = reply.GetBody<FaultException>();

从服务器端这就是我抛出异常的方式。

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext             
                                  instanceContext)
{
    throw new FaultException("MyFaultCode", new FaultCode("MyFaultCode"));
}

有人可以告诉我如何从消息中反序列化故障异常,以便我可以访问故障代码吗?

4

3 回答 3

2

这就是我实际做到的方式...... 堆栈溢出解决方案

public void AfterReceiveReply(ref Message reply, object correlationState)
    {
        if (reply.IsFault)
        {
            MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);

            XmlDictionaryReader xdr = buffer.CreateMessage().GetReaderAtBodyContents();
            XNode xn = XDocument.ReadFrom(xdr);
            string s = xn.ToString();
            XDocument xd = XDocument.Parse(s);
            XNamespace nsSoap = "http://schemas.xmlsoap.org/soap/envelope/";
            XNamespace ns = "";
            XElement xErrorCode = xd.Element(nsSoap + "Fault").Element("faultcode");

            if (xErrorCode.Value.Contains("MyFaultCode"))
            {
             // Redirect to login page
            }

            reply = buffer.CreateMessage();
            buffer.Close();
        }
    }
于 2013-07-02T12:49:29.437 回答
2

您可以直接从 System.ServiceModel.Channels.Message 类(在消息变量中)中提取故障信息:

var fault = MessageFault.CreateFault(message, int.MaxValue);

然后从这个故障中您可以读取故障代码或消息:

var error = fault.Reason.GetMatchingTranslation().Text;

总结一下,可以创建一个简单的验证方法:

private static void ValidateMessage(Message message)
    {
        if (!message.IsFault) return;
        var fault = MessageFault.CreateFault(message, int.MaxValue);
        var error = fault.Reason.GetMatchingTranslation().Text;
        //do something :)
    }
于 2015-07-27T09:54:33.830 回答
0

我不知道 .NET 是否内置了该类型,但您可以自己生成它:

  1. 下载http://schemas.xmlsoap.org/soap/envelope/
  2. 运行命令:

    svcutil /dconly /importxmltypes envelope.xml
    

但这真的是您“理想中想要做的”吗?

如果您将 FaultException 抛出为服务器,您不应该能够直接在客户端中捕获它吗?

或者更好的是,使用操作合同上的FaultContract属性来处理自定义故障异常。

于 2013-06-17T12:34:55.050 回答