Wednesday, May 4, 2011

How to Handle the WCF Error on Silverlight

By David Espino.

When sending a call to a WCF service from a Silverlight application and the service returns an error, the Silverlight client backs up only a very generic error:

The remote server returns an error: NotFound

This message does not help to know the exact error neither for the user nor the developer. Even more, it is necessary for more security to make a division of the error information: one message for the user and one detailed message for the system administrator or developer.

The first part of the error dedicated to the application administrator consists on writing the exception that the code generates on a detailed way. There are a lot of tools that allows tomake this log of errors (Log for Net, Microsoft Enterprise Library and some other). For this example, we need to provide an easy log in to the server application log where our service would be found. This method captures two parameters: One “Entity” that indicates the business entity where the error occurred (for example the Countru, State, Employee, etc) and an action, which indicates the operation that could not be performed (Save, Select, Delete, etc). With these two parameters we can deliver a friendly message to be sent to the user.

public class ExceptionLogger

{

public static string LogAndReturnError(Exception ex, string entidad, string accion)

{

StringBuilder cadenaError = new StringBuilder();

cadenaError.Append("Ocurrió un error en el servicio de la aplicación: \n\n");

cadenaError.Append("Error: ");

cadenaError.Append(ex.Message);

cadenaError.Append("\n\nStackTrace: \n\n");

cadenaError.Append(ex.StackTrace);

EventLog.WriteEntry("NombreAplicación", cadenaError.ToString(), EventLogEntryType.Error);

cadenaError = new StringBuilder();

cadenaError.Append(string.Format("Ocurrió un error al intentar {0} {1}. Contacte al administrador del sistema.", accion, entidad));

return cadenaError.ToString();

}

}

The next step would be to generate an entity as a DataContract for the object that stores errors that occur during the service.

[DataContract]

public class ServiceError

{

[DataMember]

public string Type { get; set; }

[DataMember]

public string Message { get; set; }

}

The next thing to do is to make our service operations to return us an error object into the interface layer. We will use an output parameter in our methods of service and use the kind of login error.

public void DoWork(string Parameter1, out ServiceError errorService)

{

errorService = null;

try

{

//Operaciones a realizar

}

catch (Exception ex)

{

errorService = new ServiceError

{

Message = ExceptionLogger.LogAndReturnError(ex, "Acción", "Entidad"),

Type = "Aplicación"

};

}

Finally we need a Silverlight application to consume our service. For this, we need to add a Silverlight application and then a reference of our service. Once we call our service we are going to get the following:

MyServiceClient client = new MyServiceClient ();

client.DoWorkCompleted += new EventHandler<DoWorkCompletedEventArgs>(client_DoWorkCompleted);

client.DoWorkAsync("Hola Mundo");

void client_DoWorkCompleted(object sender, DoWorkCompletedEventArgs e)

{

//Error propio de WCF

if (e.Error == null)

{

//Nuestro Parámetro de Error!!!

if (e.errorService == null)

{

if (e.Result != null)

{

//Manipular resultado

}

}

}

}

This is a very easy way to implement error management on Silverlight.

No comments:

Post a Comment