3

I am having some trouble getting back the Detail from a custom Fault Exception within a C# program. When I execute the same call in Postman, I get the response fine, but when trying to do the same thing in c#, the detail all returns null.

Exception is null

My code in c#:

        try
        {
            Client.Open();
            var response = Client.findPerson(req);
            Client.Close();
        }            
        catch (FaultException<MIAPAPIException> e)
        {

            ErrorResponse error = new ErrorResponse
            {
                ErrorCode = e.Detail.ErrorCode,
                ErrorActor = e.Detail.ErrorActor,
                TimeStamp = e.Detail.ErrorTimestamp,
                ErrorDescription = e.Detail.Description
            };
        }

The MIAPAPIException Class in the wsdl is define like this:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.8.4084.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://generic.url/exceptions")]
public partial class MIAPAPIException : object, System.ComponentModel.INotifyPropertyChanged {
    
    private string errorCodeField;
    
    private string errorActorField;
    
    private string descriptionField;
    
    private string furtherDetailsField;
    
    private string errorTimestampField;
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=0)]
    public string ErrorCode {
        get {
            return this.errorCodeField;
        }
        set {
            this.errorCodeField = value;
            this.RaisePropertyChanged("ErrorCode");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=1)]
    public string ErrorActor {
        get {
            return this.errorActorField;
        }
        set {
            this.errorActorField = value;
            this.RaisePropertyChanged("ErrorActor");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=2)]
    public string Description {
        get {
            return this.descriptionField;
        }
        set {
            this.descriptionField = value;
            this.RaisePropertyChanged("Description");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=3)]
    public string FurtherDetails {
        get {
            return this.furtherDetailsField;
        }
        set {
            this.furtherDetailsField = value;
            this.RaisePropertyChanged("FurtherDetails");
        }
    }
    
    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true, Order=4)]
    public string ErrorTimestamp {
        get {
            return this.errorTimestampField;
        }
        set {
            this.errorTimestampField = value;
            this.RaisePropertyChanged("ErrorTimestamp");
        }
    }
    
    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));
        }
    }
}

Which I can't see any issues with.

The response that I get in postman if i do the same request that i'm doing in c#:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
    <soapenv:Fault>
        <faultcode>soapenv:Server</faultcode>
        <faultstring>exceptions.MIAPAPIException</faultstring>
        <detail>
            <ns10:MIAPAPIException xmlns:ns10="http://generic.url/exceptions">
                <ErrorCode>CODE</ErrorCode>
                <ErrorActor>MSGValidator.validateSOAPMSG()</ErrorActor>
                <Description>DESC</Description>
                <FurtherDetails>DETAILS</FurtherDetails>
                <ErrorTimestamp>2022-10-11 14:34:16</ErrorTimestamp>
            </ns10:MIAPAPIException>
        </detail>
    </soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>

Im not sure what is causing this to be null when my code picks it up in c#. The ordering of the response in postman matches the ordering of the wsdl as well as the namespace matching in both.

I've tried updating the catch to be

catch (FaultException<MIAPAPIException[]> e)

But this doesn't catch the error at all. I thought this may be an array due to the <ns10:MIAPAPIException namespace at the start of the details but i appear to be incorrect here.

SilentUK
  • 151
  • 3
  • 13
  • The error message refers to a proxy. You may need to disable the proxy in c#. Normally best way is to use a sniffer like wireshark or fiddler and compare working with non working. Usually a header is missing or need to be changed. It looks like you are using HTTP so y udo not need to worry about encryption. It may be your client site requires HTTPS which may be the issue. – jdweng Nov 01 '22 at 09:44
  • Best way of debugging xml serialization is to comment out properties and classes. If a property/class is missing in c# you still will receive remaining sections. Then uncomment out the code until you isolate the issue. Right now I cannot tell if you are getting a response back or not. So the request could be bad. – jdweng Nov 01 '22 at 09:51
  • The fault exception returns but the Detail is null. I tried commenting out the properties of the custom exception but it still returned null no matter what was included. The same call in postman returns the faultexception error with the detail populated. – SilentUK Nov 08 '22 at 13:22

2 Answers2

0

Replace .Close() with .Abort(). Abort should be used when the proxy is in a faulted state. You could try the below.

    if (client.State != CommunicationState.Faulted)
    {
        client.Close();
    }
    else
    {
        client.Abort();
    }
reakt
  • 500
  • 8
  • 25
  • Unfortunately this doesnt work. The FaultException returns before we hit the Client.Abort(), its just the Detail section of the exception is null. The same call in postman returns this error but with the detail populated – SilentUK Nov 08 '22 at 13:21
0

Try following :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.Globalization;

namespace ConsoleApplication49
{

    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReader reader = XmlReader.Create(FILENAME);
            XmlSerializer serializer = new XmlSerializer(typeof(Envelope));
            Envelope envelope = (Envelope)serializer.Deserialize(reader);

        }
    }
    [XmlRoot(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public class Envelope
    {
        public Body Body { get; set; }
    }
    public class Body
    {
        public Fault Fault { get; set; }
    }
    public class Fault
    {
        [XmlElement(Namespace = "")]
        public string faultcode { get; set; }
        [XmlElement(Namespace = "")]
        public string faultstring { get; set; }
        [XmlArray(ElementName = "detail", Namespace = "")]
        [XmlArrayItem(ElementName = "MIAPAPIException", Namespace = "http://generic.url/exceptions")]
        public List<MIAPAPIException> MIAPAPIException { get; set; } 
    }
    public class MIAPAPIException
    {
        [XmlElement(Namespace = "")]
        public string ErrorCode { get; set; }
        [XmlElement(Namespace = "")]
        public string ErrorActor { get; set; }
        [XmlElement(Namespace = "")]
        public string Description { get; set; }
        [XmlElement(Namespace = "")]
        public string FurtherDetails { get; set; }

        DateTime _ErrorTimestamp { get; set; }
        [XmlElement(Namespace = "")]
        public string ErrorTimestamp { 
            get{ return  _ErrorTimestamp.ToString("yyyy-MM-dd HH:mm:ss");} 
            set{ _ErrorTimestamp = DateTime.ParseExact(value, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) ;} 
        }
    }
}
 
jdweng
  • 33,250
  • 2
  • 15
  • 20