如何从AfterReceiveReply中的WCF消息中提取faultcode

时间:2013-05-28 19:50:28

标签: .net wcf web-services soap deserialization

这是我理想的做法

    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'的'Element',命名空间'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"));
}

有人可以告诉我如何从消息中反序列化Fault Exception,以便我可以访问FaultCode吗?

3 个答案:

答案 0 :(得分:2)

这就是我实际做到的方式...... Stack Overflow solution

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();
        }
    }

答案 1 :(得分: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 :)
    }

答案 2 :(得分:0)

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

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

    svcutil /dconly /importxmltypes envelope.xml
    
  3. 但这真的是你“理想的想做”吗?

    如果您正在抛出FaultException是服务器,您是否应该能够直接在客户端中捕获它?

    或者甚至更好,使用操作合同上的FaultContract属性来处理自定义错误异常。

相关问题