FaultException.Detail返回空

时间:2010-09-08 16:38:41

标签: wcf exception-handling fault faultexception

我试图在WCF客户端上捕获给定的FaultException。我基本上需要从fault类中提取内部描述,然后我可以将它打包到另一个异常中,以便上层执行任何操作。

我已经成功完成了很多次,这次使它与众不同的是故障被声明为数组,正如你可以从抛出异常的方法之上声明的服务引用属性中看到的那样: / p>

[System.ServiceModel.FaultContractAttribute(typeof(FaultClass[]), Action = "http://whatever/", Name = "whateverBusinessFault")] 

这是我的代码:

try
{
  // call service here
}
catch (FaultException<FaultClass[]> ex)
{
  if (ex.Detail != null && ex.Detail.Length > 0)
  {
    throw new CustomException(ex.Detail[0].description);
  }
  else
  {
    throw;
  }
}

问题是详细信息(这是一个数组)在代码中总是空回来,即使我可以在WCF跟踪的SOAP响应中看到数据(描述字段等)。

所以我需要的东西肯定会回来,但由于某种原因要么它没有被反序列化,要么我无法从代码中获得它。

任何帮助表示赞赏!

更新

尝试@Darin建议但没有运气,我从XmlReader中提取的字符串是“/ r / n”:

var sb = new StringBuilder();

using (XmlReader reader = fault.GetReaderAtDetailContents())
{
  while (reader.Read())
     sb.AppendLine(reader.ReadOuterXml()); 
}

var detail = sb.ToString();

看起来细节部分根本没有出现!

5 个答案:

答案 0 :(得分:8)

我在UPS论坛上找到了解决方案:

https://developerkitcommunity.ups.com/index.php/Special:AWCforum/st/id371

“问题是visual studio没有完全映射出ErrorDetail对象.ErrorDetail节点被称为”ErrorDetail“,但为它生成的类型是”ErrorDetailType。“我编辑了生成的reference.cs类我正在使用的每项服务并添加了一个TypeName:“

答案 1 :(得分:5)

很难说问题在哪里,但我怀疑冒烟枪是这个轴网络服务没有生成标准信息。解决此问题的一种方法是自己解析XML:

try
{
    proxy.CallSomeMethod();
}
catch (FaultException ex)
{
    var fault = ex.CreateMessageFault();
    using (XmlReader reader = fault.GetReaderAtDetailContents())
    {
        // TODO: read the XML fault and extract the necessary information.
    }
}

答案 2 :(得分:2)

我想出了最简单的测试用例。我希望它会对你有所帮助。 服务器端:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [FaultContract(typeof(FaultClass[]))]
    string Crash();
}

public class Service1 : IService1
{
    public string Crash()
    {
        var exception = new FaultException<FaultClass[]>(new FaultClass[] { new FaultClass { Data = "TEST" } }, new FaultReason("Boom"));

        throw exception;
    }
}

[DataContract]
public class FaultClass
{
    [DataMember]
    public string Data { get; set; }
}

客户方:

try
{
    using (var client = new Service1Client())
    {
        client.Crash();
    }
}
catch(FaultException<FaultClass[]> e)
{
    //Break here
}

答案 3 :(得分:2)

我花了很多时间才弄清楚如何从FaultException作为字符串获取完整的详细信息。我最终想出来并编写了这个扩展方法:

public static string GetDetail(this FaultException faultException)
{
    if (faultException == null)
        throw new ArgumentNullException(nameof(faultException));

    MessageFault messageFault = faultException.CreateMessageFault();
    if (messageFault.HasDetail) {
        using (XmlDictionaryReader reader = messageFault.GetReaderAtDetailContents()) {
            return reader.ReadContentAsString();
        }
    }
    return null;
}

最初我使用的是reader.Value但是只返回多行详细信息的第一行。 reader.ReadContentAsString()似乎得到了全部内容,包括了新的内容,这就是我想要的内容。

答案 4 :(得分:1)

我在尝试与故障(特别是堆栈跟踪)进行数据通信时遇到了类似的情况。见this question。我最终通过创建自己的可序列化堆栈跟踪并将其包含在派生的FaultException类中来解决它。