Reputation: 43
Accessing SoapAPI in C# i have WSDL File Added as SeriviceRefrence in my c# classLinrery some how i am unable to catch actual Exception thrown by that API
I am getting ErrorMessage :-"An exception has been raised as a result of client data".
InnerException:-Null,
For Catching Actual Exception I tried below code:-
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;
}
}
In Above exception handling i always fouling to FaultException (ex) the above errorMessaeg from FaultException
When i try to request this API from SoapUI(readyAPI) tool manually i got below Error details which is actual error from API side that error I want in my c# Library See the below actual ERROR DETAILS
"Invalid access License Number" is Actual Message that i want to fetch
Please help me to catch that Actual Error Details "Invalid access License Number" in c# instead error-exception has been raised as a result of client data
Thank you in Advance
Upvotes: 2
Views: 3543
Reputation: 1671
In my case the real error description was:
Hard9264030The state is not supported in the Customer Integration Environment.
I realized that just NY and CA states in US are valid using my current sandbox credentials. So I suggest you change the code this way to check which error show up for you.
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;
}
}
Upvotes: 2
Reputation: 360
Yes, I fought this issue for quite a while on my own project, and finally found the solution. The WSDL generator has a problem where it mis-generates the fault object, which is why you can't access it.
To diagnose what's going on under the covers, you can use a tool like Fiddler, and monitor the traffic. UPS is returning a fault detail that has a message that will tell you what's wrong, but you can't see it because of the badly generated object.
To fix this problem in any of the UPS APIs, go into the generated Reference.cs, and just after the namespace declaration, add this class:
// 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));
}
}
}
Then search in the file for for FaultContractAttribute
. Change it to:
[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")]
You may need to adjust the namespace in the typeof() statement.
Then a block like this will catch/return the error messages:
catch (FaultException<Errors> ex)
{
return new MyResult
{
ErrorMessage =
$"UPS returned the following errors: {string.Join(", ", ex.Detail.ErrorDetail.Select(ed => ed.PrimaryErrorCode.Description))}"
};
}
That will give you the full error from the UPS API call, and you can read the API docs from there to know what's wrong.
Upvotes: 6