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 ?
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.
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.
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 ?
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:
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:publicclassServiceException :
Exception {
public ServiceException(string message) : base(message) {
}
}#if !SILVERLIGHT
[DataContract]#endif
public
classGenericResult<TResult> {
public
static TResult GetOrThrow(object wrappedResult) {
if (wrappedResult ==
null) throw
newArgumentNullException("wrappedResult");
property = resultType.GetProperty("Result"); if (property ==
null) throw
newInvalidOperationException("GenericResult: Result object passed does not expose a [Result] property.");
if (!object.ReferenceEquals(typeof(TResult),property.PropertyType)) throw
newInvalidOperationException( String.Format("GenericResult: Result object has type [{0}] rather than the expected [{1}] type.",
property.PropertyType.FullName,typeof(TResult).FullName));
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
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
SteveWong (HongKong)
Please mark post as answer if they help you
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
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
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
Software Engineer
Aprimo, Inc
Please remember to mark the replies as answers if they answered your question
Tim Favour
Member
101 Points
81 Posts
Re: WCF error handling anyone
Jun 23, 2008 06:32 PM | LINK
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
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
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
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
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.