C# 从ASMX Web服务捕获自定义异常

C# 从ASMX Web服务捕获自定义异常,c#,exception-handling,asmx,web-services,C#,Exception Handling,Asmx,Web Services,我有一个web服务,我在其中创建了一个自定义异常。假设此异常的名称为InvalidContractException 我想做的是,如果发生特定步骤,我想抛出此异常。但是,我不知道客户端如何捕获InvalidContractException以正确处理它 这是一个ASP.Net Web服务,用C#编写,在客户端调用引发错误的WCF服务时,您可以这样做 试试 将错误捕获为FaultException(YourService.FooBarFault的) 结束尝试 您必须为可能生成错误的服务方法声明Fa

我有一个web服务,我在其中创建了一个自定义异常。假设此异常的名称为InvalidContractException

我想做的是,如果发生特定步骤,我想抛出此异常。但是,我不知道客户端如何捕获InvalidContractException以正确处理它


这是一个ASP.Net Web服务,用C#

编写,在客户端调用引发错误的WCF服务时,您可以这样做

试试

将错误捕获为FaultException(YourService.FooBarFault的)

结束尝试

您必须为可能生成错误的服务方法声明FaultContract,例如

_

_
函数调用
您不能这样做:

  • Web服务不存在SOAP错误。例外情况是特定于平台的
  • 当在ASMX web服务中未处理异常时,.NET会将其转换为SOAP错误。异常的详细信息未序列化
  • 在ASMX客户端中,SOAP错误将转换为SoapException
  • ASMX web服务对SOAP错误没有适当的支持。除了客户端的SoapException之外,没有其他方法可以获取任何异常

    升级到WCF的另一个原因


    以下是WCF的工作原理,作为使用ASMX不能做的事情的示例。WCF允许您为每个web服务操作指定它可以返回哪些故障:

    [ServiceContract]
    public interface IMyServiceContract
    {
        [FaultContract(typeof(IntegerZeroFault))]
        [FaultContract(typeof(SomeOtherFault))]
        [OperationContract]
        public string GetSomeString(int someInteger);
    }
    
    [DataContract]
    public class IntegerZeroFault
    {
        [DataMember]
        public string WhichInteger {get;set;}
    }
    
    [DataContract]
    public class SomeOtherFault
    {
        [DataMember]
        public string ErrorMessage {get;set;}
    }
    
    public class MyService : IMyServiceContract
    {
        public string GetSomeString(int someInteger)
        {
            if (someInteger == 0) 
                throw new FaultException<IntegerZeroFault>(
                    new IntegerZeroFault{WhichInteger="someInteger"});
            if (someInteger != 42)
                throw new FaultException<SomeOtherFault>(
                    new SomeOtherFault{ErrorMessage ="That's not the anaswer"});
            return "Don't panic";
        }
    }
    
    [服务合同]
    公共接口IMyServiceContract
    {
    [FaultContract(typeof(IntegerZeroFault))]
    [故障合同(类型(其他故障))]
    [经营合同]
    公共字符串GetSomeString(int-someInteger);
    }
    [数据合同]
    公共类整数零错误
    {
    [数据成员]
    公共字符串WhichInteger{get;set;}
    }
    [数据合同]
    公共类其他错误
    {
    [数据成员]
    公共字符串错误消息{get;set;}
    }
    公共类MyService:IMyServiceContract
    {
    公共字符串GetSomeString(int-someInteger)
    {
    if(someInteger==0)
    抛出新的FaultException(
    新整数zerofult{WhichInteger=“someInteger”});
    if(someInteger!=42)
    抛出新的FaultException(
    新建SomeOtherFault{ErrorMessage=“这不是anaswer”});
    返回“不要惊慌”;
    }
    }
    

    例如,WCF客户端可以捕获故障异常。当我在Java客户机上尝试这一点时,它能够捕获IBM Rational Web Developer创建的从Java
    异常
    类派生的
    SomeOtherFault

    如果您的目标是抛出一个异常,以便用户能够知道出了什么问题,发生了一些特定的异常,并对其进行特殊处理,你有选择的余地。您只需要依赖客户机代理的正确实现(实际上,一个选项是自己提供客户机代理)

    有一篇有用的文章介绍了
    SoapException
    s的工作原理

    本质上,它归结为在
    SoapException
    的detail节点中编码异常详细信息(例如错误代码),然后在客户端对其进行解析,然后再重试异常


    没有办法像抛出服务边界一样重新创建异常,也没有办法自动获取任何东西,除了客户端的SoapException。

    他使用的是ASMX。他称之为“ASP.NET Web服务”,啊,好的。。我以为他在用WCF
    [ServiceContract]
    public interface IMyServiceContract
    {
        [FaultContract(typeof(IntegerZeroFault))]
        [FaultContract(typeof(SomeOtherFault))]
        [OperationContract]
        public string GetSomeString(int someInteger);
    }
    
    [DataContract]
    public class IntegerZeroFault
    {
        [DataMember]
        public string WhichInteger {get;set;}
    }
    
    [DataContract]
    public class SomeOtherFault
    {
        [DataMember]
        public string ErrorMessage {get;set;}
    }
    
    public class MyService : IMyServiceContract
    {
        public string GetSomeString(int someInteger)
        {
            if (someInteger == 0) 
                throw new FaultException<IntegerZeroFault>(
                    new IntegerZeroFault{WhichInteger="someInteger"});
            if (someInteger != 42)
                throw new FaultException<SomeOtherFault>(
                    new SomeOtherFault{ErrorMessage ="That's not the anaswer"});
            return "Don't panic";
        }
    }