Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

WCF error handling anyone RSS

9 replies

Last post Aug 14, 2008 09:01 AM by xsdf

(0)
  • Tim Favour

    Tim Favour

    Member

    101 Points

    81 Posts

    WCF error handling anyone

    Jun 23, 2008 11:23 AM | LINK

    Hi,

    I've understood that the SOAP error handling mechanism with fault contracts doesn't work in beta 2 and possibly will not work in the RTM because of browser limitations.

    Does anybody have a pattern of handling WCF errorrs in Silverlight without hacking too heavily ?

    Tim

     

  • SteveWong

    SteveWong

    Contributor

    6769 Points

    1351 Posts

    Re: WCF error handling anyone

    Jun 23, 2008 12:18 PM | LINK

     Please try to refer to sladapter's post here

    http://silverlight.net/forums/p/18852/64012.aspx#64012 

    if it still cant help, you can ask here with more details

    Regards,
    SteveWong (HongKong)
    Please mark post as answer if they help you
  • Tim Favour

    Tim Favour

    Member

    101 Points

    81 Posts

    Re: WCF error handling anyone

    Jun 23, 2008 01:26 PM | LINK

    Hi,

     I think sladapters post is for a slightly different case where there is a 404 error but the cause is unclear.

    My problem is that when I rise an custom error in the service it ends up as a 404 in my client no matter what I try to do. Creating a FaultContract for the error type does not work and I got the impression it might not work in the final release so I am looking for a clean solution to propagate server/service errors to a Silverlight client.

    Tim

  • hwsoderlund

    hwsoderlund

    Member

    429 Points

    123 Posts

    Re: WCF error handling anyone

    Jun 23, 2008 04:10 PM | LINK

    I ended up rolling my own custom error object that I pass to the client as an out parameter. It means I have to do some extra coding, but I decided it was worth it, even if it might require some refactoring when (if?) proper soap exceptions can be caught on the client side.

  • sladapter

    sladapter

    All-Star

    43609 Points

    7910 Posts

    Re: WCF error handling anyone

    Jun 23, 2008 04:34 PM | LINK

    You can read this thread and I posted how I handle exception in WCF and pass it to Silverlight:

    http://silverlight.net/forums/p/17944/60019.aspx#60019

    Sally Xu
    Software Engineer
    Aprimo, Inc

    Please remember to mark the replies as answers if they answered your question
  • Tim Favour

    Tim Favour

    Member

    101 Points

    81 Posts

    Re: WCF error handling anyone

    Jun 23, 2008 06:32 PM | LINK

    hwsoderlund

    I ended up rolling my own custom error object that I pass to the client as an out parameter. It means I have to do some extra coding, but I decided it was worth it, even if it might require some refactoring when (if?) proper soap exceptions can be caught on the client side.

    Hi,

    Sounds like a pretty nice solution, I didn't know out parameters were allowed in service calls. Do you have any example of your solution ?

    Tim

  • hwsoderlund

    hwsoderlund

    Member

    429 Points

    123 Posts

    Re: WCF error handling anyone

    Jun 24, 2008 07:01 AM | LINK

     The code is somewhat modified for clarity.

    The error object:

    [DataContract]

    public class GLSErrorObject

    {

        [DataMember]

        public string ErrorID { get; set; }

        [DataMember]

        public string ErrorMessage { get; set; }

        [DataMember]

        public DateTime ErrorTime { get; set; }

    }

     

    On the server side:

    public bool Login(string userName, string password, out GLSErrorObject GLSError)

    {

        GLSError = null;

        try

        {

            bool success = AuthenticateUser(userName, password);

     

            return success;

        }

        catch (Exception ex)

        {

            GLSError = new GLSErrorObject();

            GLSError.ErrorMessage = ex.Message;

            GLSError.ErrorTime = DateTime.Now;

            //etc...

        }

        return false;

    }

     

    And on the client side the callback method will look something like this:

    void AuthenticationClient_LoginCompleted(object sender, LoginCompletedEventArgs e)

    {

        if (e.Error != null)

        {

            throw new Exception(e.Error.Message);

            return;

        }

        else if (e.GLSError != null)

        {

            //Handle our custom error

            throw new Exception(e.GLSError.ErrorMessage);

        }

        else

        {

            //All is well

        }

        //etc...

     


     /Henrik

  • Tim Favour

    Tim Favour

    Member

    101 Points

    81 Posts

    Re: WCF error handling anyone

    Jun 24, 2008 07:57 PM | LINK

    Hi Henrik and thanks for the example code, I guess I will implement something similar.

    Btw, interesting how one can access out parameters as part of the EventArgs.

    Tim

  • jslill

    jslill

    Member

    12 Points

    17 Posts

    Re: WCF error handling anyone

    Jul 10, 2008 09:54 PM | LINK

    I implemented a slightly different approach by creating a generic class to wrap a fault message string along with the actual webservice operation result.  This ends up being pretty clean due to a bit of relection magic on the Silverlight client side.  Here's what this would look like on the service side:

    [ServiceContract]
    public interface IMyService {

        [OperationContract]
        GenericResult<double> Div(double p1,double p2);
    }
    public class MyService : IMyService {

        public GenericResult<double> Div(double p1,double p2) {

            try {

                return GenericResult<double>(p1/p2);
            }
            catch (DivideByZeroException e) {

                return GenericResult<double>(e);
            }
        }
    }

    Here’s what the Silverlight client side call to the generated WCF proxy would look like:

     

    void Div() {

        MyServiceClient client = new MyServiceClient();

        client.DivCompleted += new EventHandler<DivCompletedEventArgs>(OnDivCompleted);
        client.DivAsync(10,20);
    }

    void OnDivCompleted(object sender,DivCompletedEventArgs args) {

        double  result;

        try {

            result = GenericResult.GetOrThrow(args.Result);
        }
        catch (ServiceException e) {

            // Handle exceptions thrown by the service
        }
        catch (Exception e) {

            // Handle exceptions thrown by Silverlight or WCF
        }
    }

     

    The code for this is pretty straight forward.  The only realy trick necessary is the reflection to access the Result and Fault properties of the proxy class generated for the GenericResult<T>.  Here's the code: public class ServiceException : Exception {

        public ServiceException(string message)
            : base(message) {

        }
    }
     #if !SILVERLIGHT
    [DataContract]
    #endif
    public
    class GenericResult<TResult> {

        public static TResult GetOrThrow(object wrappedResult) {

            if (wrappedResult == null)
                throw new ArgumentNullException("wrappedResult");

            System.Type     resultType = wrappedResult.GetType();
            PropertyInfo    property;
            string          fault;

            property = resultType.GetProperty("Fault");
            if (property != null && property.PropertyType == typeof(string)) {

                fault = (string) property.GetValue(wrappedResult,null);
                if (fault != null)
                    throw new ServiceException(fault);
            }

            property = resultType.GetProperty("Result");
            if (property == null)
                throw new InvalidOperationException("GenericResult: Result object passed does not expose a [Result] property.");

            if (!object.ReferenceEquals(typeof(TResult),property.PropertyType))
                throw new InvalidOperationException(
                              String.Format("GenericResult: Result object has type [{0}] rather than the expected [{1}] type.",
                                            property.PropertyType.FullName,typeof(TResult).FullName));

            return (TResult) property.GetValue(wrappedResult,null);
        }

        public GenericResult() {

            this.Result = default(TResult);
            this.Fault  = null;
        }

        public GenericResult(TResult result) {

            this.Result = result;
            this.Fault  = null;
        }

       
    public GenericResult(Exception e) {

            this.Result = default(TResult);
            this.Fault  = e.Message;
        }

    #if !SILVERLIGHT
        [DataMember]
    #endif
        public
    TResult Result { get; set; }

    #if !SILVERLIGHT
        [DataMember]
    #endif
        public
    string Fault { get; set; }
    }
     

    Note that these classes are designed to compile in Silverlight as well as normal .NET projects.

    --------------
    Jeff Lill
    LillTek, LLC
  • xsdf

    xsdf

    Member

    177 Points

    255 Posts

    Re: WCF error handling anyone

    Aug 14, 2008 09:01 AM | LINK

    Good solution . 

    ************************************
    To be or not to be, it's not a question ,it's life.