Home Articles

WCF故障异常未传播到客户端

Asked
Viewed 1191 times
2

我有一个定义FaultContract的WCF服务:

[OperationContract]
[FaultContract(typeof(InvalidOperationException))]
[FaultContract(typeof(NotSupportedException))]
[FaultContract(typeof(Exception))]
GetSysIdsResponse GetSysIds(string id);

WCF服务捕获异常情况(空指针异常)并抛出我的FaultException:

try
        {
             ....
        }            }
        catch (InvalidOperationException ex)
        {
            // The specified DirectoryEntry is not a container
            throw new FaultException<InvalidOperationException>(ex);
        }
        catch (NotSupportedException ex)
        {
            // Search is not supported by the provider that is being used
            throw new FaultException<NotSupportedException>(ex);
        }
        catch (Exception ex)
        {
            throw new FaultException<Exception>(ex);
        }

它扔掉了最后一个 . 问题是它永远不会到达客户端 . 首先,“故障 Contract 作为服务元数据的一部分发布 . ”添加服务引用后,我在客户端元数据中看不到它 . 这是客户端代码 . 它永远不会遇到catch块catch(FaultException e)它只是说用户没有捕获FaultException . 它确实捕获了CommunicationException . 我不知道我做错了什么?

try
                {
                    response = client.GetSysIds("sgentil");
                }
                catch (FaultException<Exception> e)
                {
                    Console.WriteLine("FaultException<Exception>: " + e.Detail);
                    client.Abort();
                    return;
                }
                catch (FaultException e)
                {
                    Console.WriteLine("FaultException: " + e.Message);
                    client.Abort();
                    return;
                }
                catch (CommunicationException ex)
                {
                    Console.WriteLine("CommunicationsException");
                    client.Abort();
                    return;
                }

**我尝试了第一个答案的方法并定义了两个例外:

[DataContract]
    public class SystemFault
    {
        [DataMember]
        public string SystemOperation { get; set; }
        [DataMember]
        public string SystemReason { get; set; }
        [DataMember]
        public string SystemMessage { get; set; }
    }

    [DataContract]
    public class DatabaseFault
    {
        [DataMember]
        public string DbOperation { get; set; }
        [DataMember]
        public string DbReason { get; set; }
        [DataMember]
        public string DbMessage { get; set; }
    }

然后我申请了它:

[FaultContract(typeof(SystemFault))]
        GetSysIdsResponse GetSysIds(string id);

然后扔了:

catch (Exception ex)
            {
                SystemFault sf = new SystemFault
                    {
                        SystemOperation = "GetSystemIds",
                        SystemMessage = "Exception while obtaining AD user properties",
                        SystemReason = ex.Message
                    };
                throw new FaultException<SystemFault>(sf);
            }

客户端现在看到SystemFault类型并具有该元数据:

catch(FaultException<SystemFault> sf)
                {
                   Console.WriteLine("SystemFault {0}: {1}\n{2}",
                       sf.Detail.SystemOperation, sf.Detail.SystemMessage,
                       sf.Detail.SystemReason);
                }

但仍然在服务器上的执行停止:

throw new FaultException<SystemFault>(sf);

它说:FaultException'1不是由用户代码处理的

怎么办?

2 Answers

  • 0

    问题是您指定 FaultContract 的类型为 XXXException . 我认为这不起作用,您必须创建自己的自定义 FaultContract ,例如:

    [DataContract]
    public class InitializationFault
    {
        public InitializationFault(Exception exc, string msg)
        {
            Exception = exc;
            Message = msg;
        }
    
        [DataMember]
        public Exception Exception { get; set; }
    
        [DataMember]
        public string Message { get; set; }
    }
    

    然后你的 ServiceContract 成为:

    [OperationContract]
    [FaultContract(typeof(InitializationFault))]
    //..more
    GetSysIdsResponse GetSysIds(string id);
    

    并且您的客户端代码变为:

    try
    {
        response = client.GetSysIds("sgentil");
    }
    catch (FaultException<InitializationFault> e)
    {
         Console.WriteLine("FaultException<InitializationFault>: " + e.Detail);
        //more
    }
    
  • 0

    在我的情况下,如果接口未标记以下属性,则响应为空:

    [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults = true)]
    [System.ServiceModel.ServiceKnownTypeAttribute(typeof(Fault))]
    

    您可以使用这些属性标记操作,以使响应显示故障详细信息 .

Related