【问题标题】:Catch Actual Error details from SOAP API in C#从 C# 中的 SOAP API 捕获实际错误详细信息
【发布时间】:2018-05-25 19:11:00
【问题描述】:

在 C# 中访问 SoapAPI 我在我的 c# classLinrery 中添加了 WSDL 文件作为 ServiceRefrence,我如何无法捕获该 API 抛出的实际异常

我收到错误消息:-“由于客户端数据引发了异常”。

InnerException:-Null,

为了捕捉实际异常,我尝试了以下代码:-

 public RegisterResponse1 RegisterAccount()
        {
            try
            {
                var upss = CreateAccessRequest();
                //Process Request
                var responce = regService.ProcessRegister(CreateRegisterWebServiceRequest(shipment));
                return responce;
            }
            catch (SoapException ex)
            {
                //I never go here
                return null;
            }
            catch (FaultException ex)
            {
                //always go there
                return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

在上面的异常处理中,我总是对 FaultException(例如)上面的来自 FaultException 的 errorMessaeg 犯规

当我尝试手动从 SoapUI(readyAPI) 工具请求此 API 时,我得到以下错误详细信息,这是 API 方面的实际错误,我希望在我的 c# 库中出现该错误请参阅下面的实际错误详细信息

“无效的访问许可证号”是我要获取的实际消息

请帮助我在 c# 中捕获实际错误详细信息“无效的访问许可证号”,而不是由于客户端数据引发了错误异常

提前谢谢你

【问题讨论】:

    标签: c# api web-services wsdl


    【解决方案1】:

    是的,我在自己的项目中解决了这个问题很长一段时间,终于找到了解决方案。 WSDL 生成器存在错误生成故障对象的问题,这就是您无法访问它的原因。

    要诊断幕后发生的事情,您可以使用 Fiddler 等工具并监控流量。 UPS 正在返回一个故障详细信息,其中包含一条消息,告诉您出了什么问题,但由于生成的对象不正确,您看不到它。

    要在任何 UPS API 中解决此问题,请进入生成的 Reference.cs,并在命名空间声明之后添加此类:

    // The WSDL generator doesn't properly generate the Errors Class.  This was taken from the UPS Samples.  The FaultContractAttribute was also updated to use this class instead.
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.2612.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.ups.com/XMLSchema/XOLTWS/Error/v1.1")]
    public partial class Errors : object, System.ComponentModel.INotifyPropertyChanged
    {
    
        private ErrorDetailType[] errorDetailField;
    
        private string testElementField;
    
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute("ErrorDetail", Order = 0)]
        public ErrorDetailType[] ErrorDetail
        {
            get
            {
                return this.errorDetailField;
            }
            set
            {
                this.errorDetailField = value;
                this.RaisePropertyChanged("ErrorDetail");
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlElementAttribute(Order = 1)]
        public string TestElement
        {
            get
            {
                return this.testElementField;
            }
            set
            {
                this.testElementField = value;
                this.RaisePropertyChanged("TestElement");
            }
        }
    
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    
        protected void RaisePropertyChanged(string propertyName)
        {
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null))
            {
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    然后在文件中搜索FaultContractAttribute。将其更改为:

    [System.ServiceModel.FaultContractAttribute(typeof(Errors), Action="http://onlinetools.ups.com/webservices/ShipBinding/v1.1", Name="Errors", Namespace="http://www.ups.com/XMLSchema/XOLTWS/Error/v1.1")]
    

    您可能需要在 typeof() 语句中调整命名空间。

    然后这样的块将捕获/返回错误消息:

            catch (FaultException<Errors> ex)
            {
                return new MyResult
                {
                    ErrorMessage =
                        $"UPS returned the following errors: {string.Join(", ", ex.Detail.ErrorDetail.Select(ed => ed.PrimaryErrorCode.Description))}"
                };
            }
    

    这将为您提供 UPS API 调用的完整错误,您可以从那里阅读 API 文档以了解问题所在。

    【讨论】:

    • 你能帮我解决这个错误吗:找不到类型或命名空间名称“ErrorDetailType”(您是否缺少 using 指令或程序集引用?)我不知道要使用哪个包添加。
    【解决方案2】:

    在我的例子中,真正的错误描述是:

    Hard9264030客户集成中不支持该状态 环境。

    我意识到,使用我当前的沙盒凭据,只有美国的 NY 和 CA 州是有效的。因此,我建议您以这种方式更改代码以检查出现的错误。

    public RegisterResponse1 RegisterAccount()
    {
        try
        {
            var upss = CreateAccessRequest();
            //Process Request
            var responce = regService.ProcessRegister(CreateRegisterWebServiceRequest(shipment));
            return responce;
        }
        catch (SoapException ex)
        {
            //=====================================================================
            //put this code here and you will see the correct description of the error
            var error = ex.Detail.InnerText;
            Console.WriteLine(error);
            return null;
        }
        catch (FaultException ex)
        {
            //always go there
            return null;
        }
        catch (Exception ex)
        {
            return null;
        }
    }
    

    【讨论】:

    • 我刚看到你的回复。在我最初的开发之后,我总是使用生产环境进行地址验证。但是,我连接到运输服务的开发环境。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2018-07-25
    • 2012-12-26
    • 2010-10-27
    • 2010-11-02
    相关资源
    最近更新 更多