FaultException.Detail coming back empty

瘦欲@ 提交于 2019-12-04 02:40:30

I found the solution on a UPS Forum :

https://developerkitcommunity.ups.com/index.php/Special:AWCforum/st/id371

"The problem was the visual studio didn't quite map out the ErrorDetail objects right. The ErrorDetail node is called "ErrorDetail", but the type generated for it is "ErrorDetailType." I edited the reference.cs class generated for each service I was using and added a TypeName:"

Darin Dimitrov

It is difficult to say where the problem is but I suspect the smoking gun is this axis web service not generating standard message. One way to workaround this would be to parse the XML yourself:

try
{
    proxy.CallSomeMethod();
}
catch (FaultException ex)
{
    var fault = ex.CreateMessageFault();
    using (XmlReader reader = fault.GetReaderAtDetailContents())
    {
        // TODO: read the XML fault and extract the necessary information.
    }
}

I came up with the simplest test case I could. I hope it will help you. Server side:

[ServiceContract]
public interface IService1
{
    [OperationContract]
    [FaultContract(typeof(FaultClass[]))]
    string Crash();
}

public class Service1 : IService1
{
    public string Crash()
    {
        var exception = new FaultException<FaultClass[]>(new FaultClass[] { new FaultClass { Data = "TEST" } }, new FaultReason("Boom"));

        throw exception;
    }
}

[DataContract]
public class FaultClass
{
    [DataMember]
    public string Data { get; set; }
}

Client side:

try
{
    using (var client = new Service1Client())
    {
        client.Crash();
    }
}
catch(FaultException<FaultClass[]> e)
{
    //Break here
}

It took me ages to figure out how to get the full details message from a FaultException as a string. I eventually figured it out and wrote this extension method:

public static string GetDetail(this FaultException faultException)
{
    if (faultException == null)
        throw new ArgumentNullException(nameof(faultException));

    MessageFault messageFault = faultException.CreateMessageFault();
    if (messageFault.HasDetail) {
        using (XmlDictionaryReader reader = messageFault.GetReaderAtDetailContents()) {
            return reader.ReadContentAsString();
        }
    }
    return null;
}

Originally I was using reader.Value but that only appeared to the return the first line of a multi-line details message. reader.ReadContentAsString() appears to get the whole thing, new lines included, which is what I wanted.

Travis

I had a similar situation in trying to communicate data with faults (specifically a stack trace). See this question. I ended up solving it by creating my own serializable stack trace and including it in a derived FaultException class.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!