FaultException.Detail返回空

Joh*_*dol 9 wcf exception-handling fault faultexception

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

我已经成功完成了很多次,这次使它与众不同的是故障被声明为一个数组,正如您在抛出异常的方法之上声明的服务引用属性所看到的那样:

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

这是我的代码:

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是细节(这是一个数组)总是在代码中变回空,即使我可以在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();
Run Code Online (Sandbox Code Playgroud)

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

小智 9

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

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

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

  • 我的英雄!:)为了澄清,他在谈论的XmlTypeAttribute,加上`类型名="ErrorDetail"`那里,它会工作. (2认同)

Dar*_*rov 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.
    }
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*ais 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; }
}
Run Code Online (Sandbox Code Playgroud)

客户端:

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